Skip to content

Commit 3616567

Browse files
author
Joe Shajrawi
authored
Merge pull request #5519 from shajrawi/constant_propagation_int_ctlz
[SILOptimizer] Add ctlz support to constant propagation
2 parents f3404f3 + 77f1068 commit 3616567

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

lib/SILOptimizer/Mandatory/ConstantPropagation.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,33 @@ static SILInstruction *constantFoldIntrinsic(BuiltinInst *BI,
176176
return Op1;
177177
}
178178

179+
case llvm::Intrinsic::ctlz: {
180+
assert(BI->getArguments().size() == 2 && "Ctlz should have 2 args.");
181+
OperandValueArrayRef Args = BI->getArguments();
182+
183+
// Fold for integer constant arguments.
184+
auto *LHS = dyn_cast<IntegerLiteralInst>(Args[0]);
185+
if (!LHS) {
186+
return nullptr;
187+
}
188+
APInt LHSI = LHS->getValue();
189+
unsigned LZ = 0;
190+
// Check corner-case of source == zero
191+
if (LHSI.getLimitedValue() == 0) {
192+
auto *RHS = dyn_cast<IntegerLiteralInst>(Args[1]);
193+
if (!RHS || RHS->getValue().getBoolValue() != 0) {
194+
// Undefined
195+
return nullptr;
196+
}
197+
LZ = LHSI.getBitWidth();
198+
} else {
199+
LZ = LHSI.countLeadingZeros();
200+
}
201+
APInt LZAsAPInt = APInt(LHSI.getBitWidth(), LZ);
202+
SILBuilderWithScope B(BI);
203+
return B.createIntegerLiteral(BI->getLoc(), LHS->getType(), LZAsAPInt);
204+
}
205+
179206
case llvm::Intrinsic::sadd_with_overflow:
180207
case llvm::Intrinsic::uadd_with_overflow:
181208
case llvm::Intrinsic::ssub_with_overflow:

test/SILOptimizer/constant_propagation.sil

+30
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,36 @@ struct UInt64 {
1919
var value: Builtin.Int64
2020
}
2121

22+
sil @count_leading_zeros_corner_case : $@convention(thin) () -> Builtin.Int64 {
23+
bb0:
24+
%zero64 = integer_literal $Builtin.Int64, 0
25+
%zero1 = integer_literal $Builtin.Int1, 0
26+
%ctlz = builtin "int_ctlz_Int64"(%zero64 : $Builtin.Int64, %zero1 : $Builtin.Int1) : $Builtin.Int64
27+
return %ctlz : $Builtin.Int64
28+
29+
// CHECK-LABEL: sil @count_leading_zeros_corner_case
30+
// CHECK-NOT: integer_literal $Builtin.Int64, 0
31+
// CHECK-NOT: integer_literal $Builtin.Int1, 0
32+
// CHECK-NOT: builtin
33+
// CHECK: [[RES:%.*]] = integer_literal $Builtin.Int64, 64
34+
// CHECK-NEXT: return [[RES]] : $Builtin.Int64
35+
}
36+
37+
sil @count_leading_zeros : $@convention(thin) () -> Builtin.Int64 {
38+
bb0:
39+
%zero64 = integer_literal $Builtin.Int64, 2
40+
%zero1 = integer_literal $Builtin.Int1, 0
41+
%ctlz = builtin "int_ctlz_Int64"(%zero64 : $Builtin.Int64, %zero1 : $Builtin.Int1) : $Builtin.Int64
42+
return %ctlz : $Builtin.Int64
43+
44+
// CHECK-LABEL: sil @count_leading_zeros
45+
// CHECK-NOT: integer_literal $Builtin.Int64, 2
46+
// CHECK-NOT: integer_literal $Builtin.Int1, 0
47+
// CHECK-NOT: builtin
48+
// CHECK: [[RES:%.*]] = integer_literal $Builtin.Int64, 62
49+
// CHECK-NEXT: return [[RES]] : $Builtin.Int64
50+
}
51+
2252
// Compute an expression using a chain of arithmetic with overflow instructions: 2 * (2 + 3) - 3
2353
sil @fold_arithmetic_with_overflow : $@convention(thin) () -> Builtin.Int64 {
2454
bb0:

0 commit comments

Comments
 (0)