Skip to content

Commit

Permalink
Merge pull request swiftlang#5519 from shajrawi/constant_propagation_…
Browse files Browse the repository at this point in the history
…int_ctlz

[SILOptimizer] Add ctlz support to constant propagation
  • Loading branch information
Joe Shajrawi committed Oct 29, 2016
2 parents f3404f3 + 77f1068 commit 3616567
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
27 changes: 27 additions & 0 deletions lib/SILOptimizer/Mandatory/ConstantPropagation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,33 @@ static SILInstruction *constantFoldIntrinsic(BuiltinInst *BI,
return Op1;
}

case llvm::Intrinsic::ctlz: {
assert(BI->getArguments().size() == 2 && "Ctlz should have 2 args.");
OperandValueArrayRef Args = BI->getArguments();

// Fold for integer constant arguments.
auto *LHS = dyn_cast<IntegerLiteralInst>(Args[0]);
if (!LHS) {
return nullptr;
}
APInt LHSI = LHS->getValue();
unsigned LZ = 0;
// Check corner-case of source == zero
if (LHSI.getLimitedValue() == 0) {
auto *RHS = dyn_cast<IntegerLiteralInst>(Args[1]);
if (!RHS || RHS->getValue().getBoolValue() != 0) {
// Undefined
return nullptr;
}
LZ = LHSI.getBitWidth();
} else {
LZ = LHSI.countLeadingZeros();
}
APInt LZAsAPInt = APInt(LHSI.getBitWidth(), LZ);
SILBuilderWithScope B(BI);
return B.createIntegerLiteral(BI->getLoc(), LHS->getType(), LZAsAPInt);
}

case llvm::Intrinsic::sadd_with_overflow:
case llvm::Intrinsic::uadd_with_overflow:
case llvm::Intrinsic::ssub_with_overflow:
Expand Down
30 changes: 30 additions & 0 deletions test/SILOptimizer/constant_propagation.sil
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,36 @@ struct UInt64 {
var value: Builtin.Int64
}

sil @count_leading_zeros_corner_case : $@convention(thin) () -> Builtin.Int64 {
bb0:
%zero64 = integer_literal $Builtin.Int64, 0
%zero1 = integer_literal $Builtin.Int1, 0
%ctlz = builtin "int_ctlz_Int64"(%zero64 : $Builtin.Int64, %zero1 : $Builtin.Int1) : $Builtin.Int64
return %ctlz : $Builtin.Int64

// CHECK-LABEL: sil @count_leading_zeros_corner_case
// CHECK-NOT: integer_literal $Builtin.Int64, 0
// CHECK-NOT: integer_literal $Builtin.Int1, 0
// CHECK-NOT: builtin
// CHECK: [[RES:%.*]] = integer_literal $Builtin.Int64, 64
// CHECK-NEXT: return [[RES]] : $Builtin.Int64
}

sil @count_leading_zeros : $@convention(thin) () -> Builtin.Int64 {
bb0:
%zero64 = integer_literal $Builtin.Int64, 2
%zero1 = integer_literal $Builtin.Int1, 0
%ctlz = builtin "int_ctlz_Int64"(%zero64 : $Builtin.Int64, %zero1 : $Builtin.Int1) : $Builtin.Int64
return %ctlz : $Builtin.Int64

// CHECK-LABEL: sil @count_leading_zeros
// CHECK-NOT: integer_literal $Builtin.Int64, 2
// CHECK-NOT: integer_literal $Builtin.Int1, 0
// CHECK-NOT: builtin
// CHECK: [[RES:%.*]] = integer_literal $Builtin.Int64, 62
// CHECK-NEXT: return [[RES]] : $Builtin.Int64
}

// Compute an expression using a chain of arithmetic with overflow instructions: 2 * (2 + 3) - 3
sil @fold_arithmetic_with_overflow : $@convention(thin) () -> Builtin.Int64 {
bb0:
Expand Down

0 comments on commit 3616567

Please sign in to comment.