brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.7 KiB · 2e6fe26 Raw
299 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4declare i3 @llvm.cttz.i3(i3, i1)5declare i32 @llvm.cttz.i32(i32, i1 immarg)6declare i32 @llvm.ctlz.i32(i32, i1 immarg)7declare i64 @llvm.cttz.i64(i64, i1 immarg)8declare i64 @llvm.ctlz.i64(i64, i1 immarg)9 10declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32>, i1)11declare <2 x i32> @llvm.cttz.v2i32(<2 x i32>, i1)12 13 14declare void @use(i32)15declare void @use2(i1)16 17define i32 @select_clz_to_ctz(i32 %a) {18; CHECK-LABEL: @select_clz_to_ctz(19; CHECK-NEXT:    [[SUB1:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true)20; CHECK-NEXT:    ret i32 [[SUB1]]21;22  %sub = sub i32 0, %a23  %and = and i32 %sub, %a24  %lz = tail call i32 @llvm.ctlz.i32(i32 %and, i1 true)25  %tobool = icmp eq i32 %a, 026  %sub1 = xor i32 %lz, 3127  %cond = select i1 %tobool, i32 %lz, i32 %sub128  ret i32 %cond29}30 31define i32 @select_clz_to_ctz_preserve_flag(i32 %a) {32; CHECK-LABEL: @select_clz_to_ctz_preserve_flag(33; CHECK-NEXT:    [[COND:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 false)34; CHECK-NEXT:    ret i32 [[COND]]35;36  %sub = sub i32 0, %a37  %and = and i32 %sub, %a38  %lz = tail call i32 @llvm.ctlz.i32(i32 %and, i1 false)39  %tobool = icmp eq i32 %a, 040  %sub1 = xor i32 %lz, 3141  %cond = select i1 %tobool, i32 %lz, i32 %sub142  ret i32 %cond43}44 45define i32 @select_clz_to_ctz_constant_for_zero(i32 %a) {46; CHECK-LABEL: @select_clz_to_ctz_constant_for_zero(47; CHECK-NEXT:    [[COND:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 false)48; CHECK-NEXT:    ret i32 [[COND]]49;50  %sub = sub i32 0, %a51  %and = and i32 %sub, %a52  %lz = tail call i32 @llvm.ctlz.i32(i32 %and, i1 false)53  %tobool = icmp eq i32 %a, 054  %sub1 = xor i32 %lz, 3155  %cond = select i1 %tobool, i32 32, i32 %sub156  ret i32 %cond57}58 59define <2 x i32> @select_clz_to_ctz_vec(<2 x i32> %a) {60; CHECK-LABEL: @select_clz_to_ctz_vec(61; CHECK-NEXT:    [[COND:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[A:%.*]], i1 true)62; CHECK-NEXT:    ret <2 x i32> [[COND]]63;64  %sub = sub <2 x i32> zeroinitializer, %a65  %and = and <2 x i32> %sub, %a66  %lz = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %and, i1 true)67  %tobool = icmp eq <2 x i32> %a, zeroinitializer68  %sub1 = xor <2 x i32> %lz, <i32 31, i32 31>69  %cond = select <2 x i1> %tobool, <2 x i32> %lz, <2 x i32> %sub170  ret <2 x i32> %cond71}72 73define i32 @select_clz_to_ctz_extra_use(i32 %a) {74; CHECK-LABEL: @select_clz_to_ctz_extra_use(75; CHECK-NEXT:    [[SUB1:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true)76; CHECK-NEXT:    call void @use(i32 [[SUB1]])77; CHECK-NEXT:    ret i32 [[SUB1]]78;79  %sub = sub i32 0, %a80  %and = and i32 %sub, %a81  %lz = tail call i32 @llvm.ctlz.i32(i32 %and, i1 true)82  %tobool = icmp eq i32 %a, 083  %sub1 = xor i32 %lz, 3184  call void @use(i32 %sub1)85  %cond = select i1 %tobool, i32 %lz, i32 %sub186  ret i32 %cond87}88 89define i32 @select_clz_to_ctz_and_commuted(i32 %a) {90; CHECK-LABEL: @select_clz_to_ctz_and_commuted(91; CHECK-NEXT:    [[SUB1:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true)92; CHECK-NEXT:    ret i32 [[SUB1]]93;94  %sub = sub i32 0, %a95  %and = and i32 %a, %sub96  %lz = tail call i32 @llvm.ctlz.i32(i32 %and, i1 true)97  %tobool = icmp eq i32 %a, 098  %sub1 = xor i32 %lz, 3199  %cond = select i1 %tobool, i32 %lz, i32 %sub1100  ret i32 %cond101}102 103define i32 @select_clz_to_ctz_icmp_ne(i32 %a) {104; CHECK-LABEL: @select_clz_to_ctz_icmp_ne(105; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[A:%.*]], 0106; CHECK-NEXT:    call void @use2(i1 [[TOBOOL]])107; CHECK-NEXT:    [[SUB1:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[A]], i1 true)108; CHECK-NEXT:    ret i32 [[SUB1]]109;110  %sub = sub i32 0, %a111  %and = and i32 %sub, %a112  %lz = tail call i32 @llvm.ctlz.i32(i32 %and, i1 true)113  %tobool = icmp ne i32 %a, 0114  call void @use2(i1 %tobool)115  %sub1 = xor i32 %lz, 31116  %cond = select i1 %tobool, i32 %sub1, i32 %lz117  ret i32 %cond118}119 120define i64 @select_clz_to_ctz_i64(i64 %a) {121; CHECK-LABEL: @select_clz_to_ctz_i64(122; CHECK-NEXT:    [[SUB1:%.*]] = call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[A:%.*]], i1 true)123; CHECK-NEXT:    ret i64 [[SUB1]]124;125  %sub = sub i64 0, %a126  %and = and i64 %sub, %a127  %lz = tail call i64 @llvm.ctlz.i64(i64 %and, i1 true)128  %tobool = icmp eq i64 %a, 0129  %sub1 = xor i64 %lz, 63130  %cond = select i1 %tobool, i64 %lz, i64 %sub1131  ret i64 %cond132}133 134; Negative tests135 136define i32 @select_clz_to_ctz_wrong_sub(i32 %a) {137; CHECK-LABEL: @select_clz_to_ctz_wrong_sub(138; CHECK-NEXT:    [[SUB:%.*]] = sub i32 1, [[A:%.*]]139; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[A]]140; CHECK-NEXT:    [[LZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[AND]], i1 true)141; CHECK-NEXT:    [[SUB1:%.*]] = xor i32 [[LZ]], 31142; CHECK-NEXT:    ret i32 [[SUB1]]143;144  %sub = sub i32 1, %a145  %and = and i32 %sub, %a146  %lz = tail call i32 @llvm.ctlz.i32(i32 %and, i1 true)147  %tobool = icmp eq i32 %a, 0148  %sub1 = xor i32 %lz, 31149  %cond = select i1 %tobool, i32 %lz, i32 %sub1150  ret i32 %cond151}152 153; TODO: https://alive2.llvm.org/ce/z/X6QjcB154define i64 @select_clz_to_ctz_i64_wrong_xor(i64 %a) {155; CHECK-LABEL: @select_clz_to_ctz_i64_wrong_xor(156; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[A:%.*]]157; CHECK-NEXT:    [[AND:%.*]] = and i64 [[A]], [[SUB]]158; CHECK-NEXT:    [[LZ:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[AND]], i1 true)159; CHECK-NEXT:    [[SUB1:%.*]] = or disjoint i64 [[LZ]], 64160; CHECK-NEXT:    ret i64 [[SUB1]]161;162  %sub = sub i64 0, %a163  %and = and i64 %sub, %a164  %lz = tail call i64 @llvm.ctlz.i64(i64 %and, i1 true)165  %tobool = icmp eq i64 %a, 0166  %sub1 = xor i64 %lz, 64167  %cond = select i1 %tobool, i64 %lz, i64 %sub1168  ret i64 %cond169}170 171define i64 @select_clz_to_ctz_i64_wrong_icmp_cst(i64 %a) {172; CHECK-LABEL: @select_clz_to_ctz_i64_wrong_icmp_cst(173; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 1174; CHECK-NEXT:    [[SUB1:%.*]] = call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[A]], i1 true)175; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i64 63, i64 [[SUB1]]176; CHECK-NEXT:    ret i64 [[COND]]177;178  %sub = sub i64 0, %a179  %and = and i64 %sub, %a180  %lz = tail call i64 @llvm.ctlz.i64(i64 %and, i1 true)181  %tobool = icmp eq i64 %a, 1182  %sub1 = xor i64 %lz, 63183  %cond = select i1 %tobool, i64 %lz, i64 %sub1184  ret i64 %cond185}186 187define i64 @select_clz_to_ctz_i64_wrong_icmp_pred(i64 %a) {188; CHECK-LABEL: @select_clz_to_ctz_i64_wrong_icmp_pred(189; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[A:%.*]]190; CHECK-NEXT:    [[AND:%.*]] = and i64 [[A]], [[SUB]]191; CHECK-NEXT:    [[LZ:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[AND]], i1 true)192; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp slt i64 [[A]], 0193; CHECK-NEXT:    [[SUB1:%.*]] = xor i64 [[LZ]], 63194; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[LZ]], i64 [[SUB1]]195; CHECK-NEXT:    ret i64 [[COND]]196;197  %sub = sub i64 0, %a198  %and = and i64 %sub, %a199  %lz = tail call i64 @llvm.ctlz.i64(i64 %and, i1 true)200  %tobool = icmp slt i64 %a, 0201  %sub1 = xor i64 %lz, 63202  %cond = select i1 %tobool, i64 %lz, i64 %sub1203  ret i64 %cond204}205 206define <2 x i32> @select_clz_to_ctz_vec_with_undef(<2 x i32> %a) {207; CHECK-LABEL: @select_clz_to_ctz_vec_with_undef(208; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i32> zeroinitializer, [[A:%.*]]209; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[A]], [[SUB]]210; CHECK-NEXT:    [[LZ:%.*]] = tail call range(i32 0, 33) <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[AND]], i1 true)211; CHECK-NEXT:    [[SUB1:%.*]] = xor <2 x i32> [[LZ]], <i32 31, i32 undef>212; CHECK-NEXT:    ret <2 x i32> [[SUB1]]213;214  %sub = sub <2 x i32> zeroinitializer, %a215  %and = and <2 x i32> %sub, %a216  %lz = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %and, i1 true)217  %tobool = icmp eq <2 x i32> %a, zeroinitializer218  %sub1 = xor <2 x i32> %lz, <i32 31, i32 undef>219  %cond = select <2 x i1> %tobool, <2 x i32> %lz, <2 x i32> %sub1220  ret <2 x i32> %cond221}222 223define i32 @select_clz_to_ctz_wrong_constant_for_zero(i32 %a) {224; CHECK-LABEL: @select_clz_to_ctz_wrong_constant_for_zero(225; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[A:%.*]]226; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A]], [[SUB]]227; CHECK-NEXT:    [[LZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[AND]], i1 false)228; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0229; CHECK-NEXT:    [[SUB1:%.*]] = xor i32 [[LZ]], 31230; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 31, i32 [[SUB1]]231; CHECK-NEXT:    ret i32 [[COND]]232;233  %sub = sub i32 0, %a234  %and = and i32 %sub, %a235  %lz = tail call i32 @llvm.ctlz.i32(i32 %and, i1 false)236  %tobool = icmp eq i32 %a, 0237  %sub1 = xor i32 %lz, 31238  %cond = select i1 %tobool, i32 31, i32 %sub1239  ret i32 %cond240}241 242define i4 @PR45762(i3 %x4) {243; CHECK-LABEL: @PR45762(244; CHECK-NEXT:    [[T4:%.*]] = call range(i3 0, -4) i3 @llvm.cttz.i3(i3 [[X4:%.*]], i1 false)245; CHECK-NEXT:    [[T7:%.*]] = zext nneg i3 [[T4]] to i4246; CHECK-NEXT:    [[ONE_HOT_16:%.*]] = shl nuw i4 1, [[T7]]247; CHECK-NEXT:    [[OR_69_NOT:%.*]] = icmp eq i3 [[X4]], 0248; CHECK-NEXT:    [[UMUL_231:%.*]] = shl i4 [[ONE_HOT_16]], [[T7]]249; CHECK-NEXT:    [[SEL_71:%.*]] = select i1 [[OR_69_NOT]], i4 -8, i4 [[UMUL_231]]250; CHECK-NEXT:    ret i4 [[SEL_71]]251;252  %t4 = call i3 @llvm.cttz.i3(i3 %x4, i1 false)253  %t5 = icmp eq i3 %x4, 0254  %t6 = select i1 %t5, i3 3, i3 %t4255  %t7 = zext i3 %t6 to i4256  %one_hot_16 = shl i4 1, %t7257  %t8 = lshr i4 %one_hot_16, 0258  %bit_slice_61 = trunc i4 %t8 to i1259  %t9 = lshr i4 %one_hot_16, 1260  %bit_slice_62 = trunc i4 %t9 to i1261  %t10 = lshr i4 %one_hot_16, 2262  %bit_slice_64 = trunc i4 %t10 to i1263  %t11 = or i1 %bit_slice_61, %bit_slice_62264  %or_69 = or i1 %t11, %bit_slice_64265  %umul_23 = mul i4 %one_hot_16, %one_hot_16266  %t12 = icmp eq i1 %or_69, false267  %sel_71 = select i1 %t12, i4 %one_hot_16, i4 %umul_23268  ret i4 %sel_71269}270 271define i4 @PR45762_logical(i3 %x4) {272; CHECK-LABEL: @PR45762_logical(273; CHECK-NEXT:    [[T4:%.*]] = call range(i3 0, -4) i3 @llvm.cttz.i3(i3 [[X4:%.*]], i1 false)274; CHECK-NEXT:    [[T7:%.*]] = zext nneg i3 [[T4]] to i4275; CHECK-NEXT:    [[ONE_HOT_16:%.*]] = shl nuw i4 1, [[T7]]276; CHECK-NEXT:    [[OR_69_NOT:%.*]] = icmp eq i3 [[X4]], 0277; CHECK-NEXT:    [[UMUL_231:%.*]] = shl i4 [[ONE_HOT_16]], [[T7]]278; CHECK-NEXT:    [[SEL_71:%.*]] = select i1 [[OR_69_NOT]], i4 -8, i4 [[UMUL_231]]279; CHECK-NEXT:    ret i4 [[SEL_71]]280;281  %t4 = call i3 @llvm.cttz.i3(i3 %x4, i1 false)282  %t5 = icmp eq i3 %x4, 0283  %t6 = select i1 %t5, i3 3, i3 %t4284  %t7 = zext i3 %t6 to i4285  %one_hot_16 = shl i4 1, %t7286  %t8 = lshr i4 %one_hot_16, 0287  %bit_slice_61 = trunc i4 %t8 to i1288  %t9 = lshr i4 %one_hot_16, 1289  %bit_slice_62 = trunc i4 %t9 to i1290  %t10 = lshr i4 %one_hot_16, 2291  %bit_slice_64 = trunc i4 %t10 to i1292  %t11 = select i1 %bit_slice_61, i1 true, i1 %bit_slice_62293  %or_69 = select i1 %t11, i1 true, i1 %bit_slice_64294  %umul_23 = mul i4 %one_hot_16, %one_hot_16295  %t12 = icmp eq i1 %or_69, false296  %sel_71 = select i1 %t12, i4 %one_hot_16, i4 %umul_23297  ret i4 %sel_71298}299