xref: /llvm-project/llvm/test/Transforms/InstCombine/fold-log2-ceil-idiom.ll (revision 095d49da76be09143582e07a807c86d3b4334dec)
11220c9baSYingwei Zheng; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
21220c9baSYingwei Zheng; RUN: opt < %s -passes=instcombine -S | FileCheck %s
31220c9baSYingwei Zheng
41220c9baSYingwei Zhengdefine i32 @log2_ceil_idiom(i32 %x) {
51220c9baSYingwei Zheng; CHECK-LABEL: define i32 @log2_ceil_idiom(
61220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
71220c9baSYingwei Zheng; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X]], -1
8b8f3024aSAndreas Jonson; CHECK-NEXT:    [[TMP2:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false)
91220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = sub nuw nsw i32 32, [[TMP2]]
101220c9baSYingwei Zheng; CHECK-NEXT:    ret i32 [[RET]]
111220c9baSYingwei Zheng;
121220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
131220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
141220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
151220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
161220c9baSYingwei Zheng  %zext = zext i1 %cmp to i32
171220c9baSYingwei Zheng  %ret = add i32 %xor, %zext
181220c9baSYingwei Zheng  ret i32 %ret
191220c9baSYingwei Zheng}
201220c9baSYingwei Zheng
211220c9baSYingwei Zhengdefine i5 @log2_ceil_idiom_trunc(i32 %x) {
221220c9baSYingwei Zheng; CHECK-LABEL: define i5 @log2_ceil_idiom_trunc(
231220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
241220c9baSYingwei Zheng; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X]], -1
25b8f3024aSAndreas Jonson; CHECK-NEXT:    [[TMP2:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false)
261220c9baSYingwei Zheng; CHECK-NEXT:    [[TMP3:%.*]] = sub nsw i32 0, [[TMP2]]
271220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = trunc i32 [[TMP3]] to i5
281220c9baSYingwei Zheng; CHECK-NEXT:    ret i5 [[RET]]
291220c9baSYingwei Zheng;
301220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
311220c9baSYingwei Zheng  %trunc = trunc i32 %ctlz to i5
321220c9baSYingwei Zheng  %xor = xor i5 %trunc, 31
331220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
341220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
351220c9baSYingwei Zheng  %zext = zext i1 %cmp to i5
361220c9baSYingwei Zheng  %ret = add i5 %xor, %zext
371220c9baSYingwei Zheng  ret i5 %ret
381220c9baSYingwei Zheng}
391220c9baSYingwei Zheng
401220c9baSYingwei Zhengdefine i64 @log2_ceil_idiom_zext(i32 %x) {
411220c9baSYingwei Zheng; CHECK-LABEL: define i64 @log2_ceil_idiom_zext(
421220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
431220c9baSYingwei Zheng; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X]], -1
44b8f3024aSAndreas Jonson; CHECK-NEXT:    [[TMP2:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false)
451220c9baSYingwei Zheng; CHECK-NEXT:    [[TMP3:%.*]] = sub nuw nsw i32 32, [[TMP2]]
4617162b61SNoah Goldstein; CHECK-NEXT:    [[RET:%.*]] = zext nneg i32 [[TMP3]] to i64
471220c9baSYingwei Zheng; CHECK-NEXT:    ret i64 [[RET]]
481220c9baSYingwei Zheng;
491220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
501220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
511220c9baSYingwei Zheng  %ext = zext nneg i32 %xor to i64
521220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
531220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
541220c9baSYingwei Zheng  %zext = zext i1 %cmp to i64
551220c9baSYingwei Zheng  %ret = add i64 %ext, %zext
561220c9baSYingwei Zheng  ret i64 %ret
571220c9baSYingwei Zheng}
581220c9baSYingwei Zheng
591220c9baSYingwei Zhengdefine i32 @log2_ceil_idiom_power2_test2(i32 %x) {
601220c9baSYingwei Zheng; CHECK-LABEL: define i32 @log2_ceil_idiom_power2_test2(
611220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
621220c9baSYingwei Zheng; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X]], -1
63b8f3024aSAndreas Jonson; CHECK-NEXT:    [[TMP2:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false)
641220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = sub nuw nsw i32 32, [[TMP2]]
651220c9baSYingwei Zheng; CHECK-NEXT:    ret i32 [[RET]]
661220c9baSYingwei Zheng;
671220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
681220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
691220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
701220c9baSYingwei Zheng  %cmp = icmp ne i32 %ctpop, 1
711220c9baSYingwei Zheng  %zext = zext i1 %cmp to i32
721220c9baSYingwei Zheng  %ret = add i32 %xor, %zext
731220c9baSYingwei Zheng  ret i32 %ret
741220c9baSYingwei Zheng}
751220c9baSYingwei Zheng
761220c9baSYingwei Zhengdefine i32 @log2_ceil_idiom_commuted(i32 %x) {
771220c9baSYingwei Zheng; CHECK-LABEL: define i32 @log2_ceil_idiom_commuted(
781220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
791220c9baSYingwei Zheng; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X]], -1
80b8f3024aSAndreas Jonson; CHECK-NEXT:    [[TMP2:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false)
811220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = sub nuw nsw i32 32, [[TMP2]]
821220c9baSYingwei Zheng; CHECK-NEXT:    ret i32 [[RET]]
831220c9baSYingwei Zheng;
841220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
851220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
861220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
871220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
881220c9baSYingwei Zheng  %zext = zext i1 %cmp to i32
891220c9baSYingwei Zheng  %ret = add i32 %zext, %xor
901220c9baSYingwei Zheng  ret i32 %ret
911220c9baSYingwei Zheng}
921220c9baSYingwei Zheng
931220c9baSYingwei Zhengdefine i32 @log2_ceil_idiom_multiuse1(i32 %x) {
941220c9baSYingwei Zheng; CHECK-LABEL: define i32 @log2_ceil_idiom_multiuse1(
951220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
96b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
971220c9baSYingwei Zheng; CHECK-NEXT:    call void @use32(i32 [[CTPOP]])
981220c9baSYingwei Zheng; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X]], -1
99b8f3024aSAndreas Jonson; CHECK-NEXT:    [[TMP2:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false)
1001220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = sub nuw nsw i32 32, [[TMP2]]
1011220c9baSYingwei Zheng; CHECK-NEXT:    ret i32 [[RET]]
1021220c9baSYingwei Zheng;
1031220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
1041220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
1051220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
1061220c9baSYingwei Zheng  call void @use32(i32 %ctpop)
1071220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
1081220c9baSYingwei Zheng  %zext = zext i1 %cmp to i32
1091220c9baSYingwei Zheng  %ret = add i32 %xor, %zext
1101220c9baSYingwei Zheng  ret i32 %ret
1111220c9baSYingwei Zheng}
1121220c9baSYingwei Zheng
1131220c9baSYingwei Zheng; Negative tests
1141220c9baSYingwei Zheng
1151220c9baSYingwei Zhengdefine i32 @log2_ceil_idiom_x_may_be_zero(i32 %x) {
1161220c9baSYingwei Zheng; CHECK-LABEL: define i32 @log2_ceil_idiom_x_may_be_zero(
1171220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
118b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTLZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X]], i1 false)
1191220c9baSYingwei Zheng; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[CTLZ]], 31
120b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
121*095d49daSYingwei Zheng; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[CTPOP]], 1
1221220c9baSYingwei Zheng; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
1231220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[XOR]], [[ZEXT]]
1241220c9baSYingwei Zheng; CHECK-NEXT:    ret i32 [[RET]]
1251220c9baSYingwei Zheng;
1261220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
1271220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
1281220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
1291220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
1301220c9baSYingwei Zheng  %zext = zext i1 %cmp to i32
1311220c9baSYingwei Zheng  %ret = add i32 %xor, %zext
1321220c9baSYingwei Zheng  ret i32 %ret
1331220c9baSYingwei Zheng}
1341220c9baSYingwei Zheng
1351220c9baSYingwei Zhengdefine i4 @log2_ceil_idiom_trunc_too_short(i32 %x) {
1361220c9baSYingwei Zheng; CHECK-LABEL: define i4 @log2_ceil_idiom_trunc_too_short(
1371220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
138b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTLZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
1391220c9baSYingwei Zheng; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[CTLZ]] to i4
1401220c9baSYingwei Zheng; CHECK-NEXT:    [[XOR:%.*]] = xor i4 [[TRUNC]], -1
141b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
142*095d49daSYingwei Zheng; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[CTPOP]], 1
1431220c9baSYingwei Zheng; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i4
1441220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = add i4 [[XOR]], [[ZEXT]]
1451220c9baSYingwei Zheng; CHECK-NEXT:    ret i4 [[RET]]
1461220c9baSYingwei Zheng;
1471220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
1481220c9baSYingwei Zheng  %trunc = trunc i32 %ctlz to i4
1491220c9baSYingwei Zheng  %xor = xor i4 %trunc, 31
1501220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
1511220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
1521220c9baSYingwei Zheng  %zext = zext i1 %cmp to i4
1531220c9baSYingwei Zheng  %ret = add i4 %xor, %zext
1541220c9baSYingwei Zheng  ret i4 %ret
1551220c9baSYingwei Zheng}
1561220c9baSYingwei Zheng
1571220c9baSYingwei Zhengdefine i32 @log2_ceil_idiom_mismatched_operands(i32 %x, i32 %y) {
1581220c9baSYingwei Zheng; CHECK-LABEL: define i32 @log2_ceil_idiom_mismatched_operands(
1591220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
160b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTLZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
1611220c9baSYingwei Zheng; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[CTLZ]], 31
162b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y]])
163*095d49daSYingwei Zheng; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[CTPOP]], 1
1641220c9baSYingwei Zheng; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
1651220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[XOR]], [[ZEXT]]
1661220c9baSYingwei Zheng; CHECK-NEXT:    ret i32 [[RET]]
1671220c9baSYingwei Zheng;
1681220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
1691220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
1701220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %y)
1711220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
1721220c9baSYingwei Zheng  %zext = zext i1 %cmp to i32
1731220c9baSYingwei Zheng  %ret = add i32 %xor, %zext
1741220c9baSYingwei Zheng  ret i32 %ret
1751220c9baSYingwei Zheng}
1761220c9baSYingwei Zheng
1771220c9baSYingwei Zhengdefine i32 @log2_ceil_idiom_wrong_constant(i32 %x) {
1781220c9baSYingwei Zheng; CHECK-LABEL: define i32 @log2_ceil_idiom_wrong_constant(
1791220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
180b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTLZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
1811220c9baSYingwei Zheng; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[CTLZ]], 30
182b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
183*095d49daSYingwei Zheng; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[CTPOP]], 1
1841220c9baSYingwei Zheng; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
1851220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[XOR]], [[ZEXT]]
1861220c9baSYingwei Zheng; CHECK-NEXT:    ret i32 [[RET]]
1871220c9baSYingwei Zheng;
1881220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
1891220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 30
1901220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
1911220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
1921220c9baSYingwei Zheng  %zext = zext i1 %cmp to i32
1931220c9baSYingwei Zheng  %ret = add i32 %xor, %zext
1941220c9baSYingwei Zheng  ret i32 %ret
1951220c9baSYingwei Zheng}
1961220c9baSYingwei Zheng
1971220c9baSYingwei Zhengdefine i32 @log2_ceil_idiom_not_a_power2_test1(i32 %x) {
1981220c9baSYingwei Zheng; CHECK-LABEL: define i32 @log2_ceil_idiom_not_a_power2_test1(
1991220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
200b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTLZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
2011220c9baSYingwei Zheng; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[CTLZ]], 31
202b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
2031220c9baSYingwei Zheng; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CTPOP]], 1
2041220c9baSYingwei Zheng; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
2051220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[XOR]], [[ZEXT]]
2061220c9baSYingwei Zheng; CHECK-NEXT:    ret i32 [[RET]]
2071220c9baSYingwei Zheng;
2081220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
2091220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
2101220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
2111220c9baSYingwei Zheng  %cmp = icmp eq i32 %ctpop, 1
2121220c9baSYingwei Zheng  %zext = zext i1 %cmp to i32
2131220c9baSYingwei Zheng  %ret = add i32 %xor, %zext
2141220c9baSYingwei Zheng  ret i32 %ret
2151220c9baSYingwei Zheng}
2161220c9baSYingwei Zheng
2171220c9baSYingwei Zhengdefine i32 @log2_ceil_idiom_not_a_power2_test2(i32 %x) {
2181220c9baSYingwei Zheng; CHECK-LABEL: define i32 @log2_ceil_idiom_not_a_power2_test2(
2191220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
220b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTLZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
2211220c9baSYingwei Zheng; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[CTLZ]], 31
222b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
223*095d49daSYingwei Zheng; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[CTPOP]], 2
2241220c9baSYingwei Zheng; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
2251220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[XOR]], [[ZEXT]]
2261220c9baSYingwei Zheng; CHECK-NEXT:    ret i32 [[RET]]
2271220c9baSYingwei Zheng;
2281220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
2291220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
2301220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
2311220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 2
2321220c9baSYingwei Zheng  %zext = zext i1 %cmp to i32
2331220c9baSYingwei Zheng  %ret = add i32 %xor, %zext
2341220c9baSYingwei Zheng  ret i32 %ret
2351220c9baSYingwei Zheng}
2361220c9baSYingwei Zheng
2371220c9baSYingwei Zhengdefine i32 @log2_ceil_idiom_multiuse2(i32 %x) {
2381220c9baSYingwei Zheng; CHECK-LABEL: define i32 @log2_ceil_idiom_multiuse2(
2391220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
240b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTLZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
2411220c9baSYingwei Zheng; CHECK-NEXT:    call void @use32(i32 [[CTLZ]])
2421220c9baSYingwei Zheng; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[CTLZ]], 31
243b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
244*095d49daSYingwei Zheng; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[CTPOP]], 1
2451220c9baSYingwei Zheng; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
2461220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[XOR]], [[ZEXT]]
2471220c9baSYingwei Zheng; CHECK-NEXT:    ret i32 [[RET]]
2481220c9baSYingwei Zheng;
2491220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
2501220c9baSYingwei Zheng  call void @use32(i32 %ctlz)
2511220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
2521220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
2531220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
2541220c9baSYingwei Zheng  %zext = zext i1 %cmp to i32
2551220c9baSYingwei Zheng  %ret = add i32 %xor, %zext
2561220c9baSYingwei Zheng  ret i32 %ret
2571220c9baSYingwei Zheng}
2581220c9baSYingwei Zheng
2591220c9baSYingwei Zhengdefine i32 @log2_ceil_idiom_multiuse3(i32 %x) {
2601220c9baSYingwei Zheng; CHECK-LABEL: define i32 @log2_ceil_idiom_multiuse3(
2611220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
262b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTLZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
2631220c9baSYingwei Zheng; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[CTLZ]], 31
2641220c9baSYingwei Zheng; CHECK-NEXT:    call void @use32(i32 [[XOR]])
265b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
266*095d49daSYingwei Zheng; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[CTPOP]], 1
2671220c9baSYingwei Zheng; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
2681220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[XOR]], [[ZEXT]]
2691220c9baSYingwei Zheng; CHECK-NEXT:    ret i32 [[RET]]
2701220c9baSYingwei Zheng;
2711220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
2721220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
2731220c9baSYingwei Zheng  call void @use32(i32 %xor)
2741220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
2751220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
2761220c9baSYingwei Zheng  %zext = zext i1 %cmp to i32
2771220c9baSYingwei Zheng  %ret = add i32 %xor, %zext
2781220c9baSYingwei Zheng  ret i32 %ret
2791220c9baSYingwei Zheng}
2801220c9baSYingwei Zheng
2811220c9baSYingwei Zhengdefine i5 @log2_ceil_idiom_trunc_multiuse4(i32 %x) {
2821220c9baSYingwei Zheng; CHECK-LABEL: define i5 @log2_ceil_idiom_trunc_multiuse4(
2831220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
284b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTLZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
285b1094776SYingwei Zheng; CHECK-NEXT:    [[TRUNC:%.*]] = trunc nuw i32 [[CTLZ]] to i5
2861220c9baSYingwei Zheng; CHECK-NEXT:    call void @use5(i5 [[TRUNC]])
2871220c9baSYingwei Zheng; CHECK-NEXT:    [[XOR:%.*]] = xor i5 [[TRUNC]], -1
288b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
289*095d49daSYingwei Zheng; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[CTPOP]], 1
2901220c9baSYingwei Zheng; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i5
2911220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = add i5 [[XOR]], [[ZEXT]]
2921220c9baSYingwei Zheng; CHECK-NEXT:    ret i5 [[RET]]
2931220c9baSYingwei Zheng;
2941220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
2951220c9baSYingwei Zheng  %trunc = trunc i32 %ctlz to i5
2961220c9baSYingwei Zheng  call void @use5(i5 %trunc)
2971220c9baSYingwei Zheng  %xor = xor i5 %trunc, 31
2981220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
2991220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
3001220c9baSYingwei Zheng  %zext = zext i1 %cmp to i5
3011220c9baSYingwei Zheng  %ret = add i5 %xor, %zext
3021220c9baSYingwei Zheng  ret i5 %ret
3031220c9baSYingwei Zheng}
3041220c9baSYingwei Zheng
3051220c9baSYingwei Zhengdefine i64 @log2_ceil_idiom_zext_multiuse5(i32 %x) {
3061220c9baSYingwei Zheng; CHECK-LABEL: define i64 @log2_ceil_idiom_zext_multiuse5(
3071220c9baSYingwei Zheng; CHECK-SAME: i32 [[X:%.*]]) {
308b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTLZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
3091220c9baSYingwei Zheng; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[CTLZ]], 31
3101220c9baSYingwei Zheng; CHECK-NEXT:    [[EXT:%.*]] = zext nneg i32 [[XOR]] to i64
3111220c9baSYingwei Zheng; CHECK-NEXT:    call void @use64(i64 [[EXT]])
312b8f3024aSAndreas Jonson; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
313*095d49daSYingwei Zheng; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[CTPOP]], 1
3141220c9baSYingwei Zheng; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i64
3151220c9baSYingwei Zheng; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i64 [[EXT]], [[ZEXT]]
3161220c9baSYingwei Zheng; CHECK-NEXT:    ret i64 [[RET]]
3171220c9baSYingwei Zheng;
3181220c9baSYingwei Zheng  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
3191220c9baSYingwei Zheng  %xor = xor i32 %ctlz, 31
3201220c9baSYingwei Zheng  %ext = zext nneg i32 %xor to i64
3211220c9baSYingwei Zheng  call void @use64(i64 %ext)
3221220c9baSYingwei Zheng  %ctpop = tail call i32 @llvm.ctpop.i32(i32 %x)
3231220c9baSYingwei Zheng  %cmp = icmp ugt i32 %ctpop, 1
3241220c9baSYingwei Zheng  %zext = zext i1 %cmp to i64
3251220c9baSYingwei Zheng  %ret = add i64 %ext, %zext
3261220c9baSYingwei Zheng  ret i64 %ret
3271220c9baSYingwei Zheng}
3281220c9baSYingwei Zheng
3291220c9baSYingwei Zhengdeclare void @use5(i5)
3301220c9baSYingwei Zhengdeclare void @use32(i32)
3311220c9baSYingwei Zhengdeclare void @use64(i64)
3321220c9baSYingwei Zheng
3331220c9baSYingwei Zhengdeclare i32 @llvm.ctlz.i32(i32, i1)
3341220c9baSYingwei Zhengdeclare i32 @llvm.ctpop.i32(i32)
335