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