brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.0 KiB · 829213b Raw
393 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -S -passes=instcombine | FileCheck %s3 4declare i32 @llvm.cttz.i32(i32, i1)5declare i32 @llvm.ctlz.i32(i32, i1)6declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>, i1)7declare void @use(i32)8 9define i32 @cttz_zext_zero_undef(i16 %x) {10; CHECK-LABEL: @cttz_zext_zero_undef(11; CHECK-NEXT:    [[TMP1:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 true)12; CHECK-NEXT:    [[TZ:%.*]] = zext nneg i16 [[TMP1]] to i3213; CHECK-NEXT:    ret i32 [[TZ]]14;15  %z = zext i16 %x to i3216  %tz = call i32 @llvm.cttz.i32(i32 %z, i1 true)17  ret i32 %tz18}19 20define i32 @cttz_zext_zero_def(i16 %x) {21; CHECK-LABEL: @cttz_zext_zero_def(22; CHECK-NEXT:    [[Z:%.*]] = zext i16 [[X:%.*]] to i3223; CHECK-NEXT:    [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Z]], i1 false)24; CHECK-NEXT:    ret i32 [[TZ]]25;26  %z = zext i16 %x to i3227  %tz = call i32 @llvm.cttz.i32(i32 %z, i1 false)28  ret i32 %tz29}30 31define i32 @cttz_zext_zero_undef_extra_use(i16 %x) {32; CHECK-LABEL: @cttz_zext_zero_undef_extra_use(33; CHECK-NEXT:    [[Z:%.*]] = zext i16 [[X:%.*]] to i3234; CHECK-NEXT:    call void @use(i32 [[Z]])35; CHECK-NEXT:    [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Z]], i1 true)36; CHECK-NEXT:    ret i32 [[TZ]]37;38  %z = zext i16 %x to i3239  call void @use(i32 %z)40  %tz = call i32 @llvm.cttz.i32(i32 %z, i1 true)41  ret i32 %tz42}43 44define <2 x i64> @cttz_zext_zero_undef_vec(<2 x i32> %x) {45; CHECK-LABEL: @cttz_zext_zero_undef_vec(46; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X:%.*]], i1 true)47; CHECK-NEXT:    [[TZ:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>48; CHECK-NEXT:    ret <2 x i64> [[TZ]]49;50  %z = zext <2 x i32> %x to <2 x i64>51  %tz = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %z, i1 true)52  ret <2 x i64> %tz53}54 55define <2 x i64> @cttz_zext_zero_def_vec(<2 x i32> %x) {56; CHECK-LABEL: @cttz_zext_zero_def_vec(57; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i32> [[X:%.*]] to <2 x i64>58; CHECK-NEXT:    [[TZ:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[Z]], i1 false)59; CHECK-NEXT:    ret <2 x i64> [[TZ]]60;61  %z = zext <2 x i32> %x to <2 x i64>62  %tz = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %z, i1 false)63  ret <2 x i64> %tz64}65 66define i32 @cttz_sext_zero_undef(i16 %x) {67; CHECK-LABEL: @cttz_sext_zero_undef(68; CHECK-NEXT:    [[TMP1:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 true)69; CHECK-NEXT:    [[TZ:%.*]] = zext nneg i16 [[TMP1]] to i3270; CHECK-NEXT:    ret i32 [[TZ]]71;72  %s = sext i16 %x to i3273  %tz = call i32 @llvm.cttz.i32(i32 %s, i1 true)74  ret i32 %tz75}76 77define i32 @cttz_sext_zero_def(i16 %x) {78; CHECK-LABEL: @cttz_sext_zero_def(79; CHECK-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i3280; CHECK-NEXT:    [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[TMP1]], i1 false)81; CHECK-NEXT:    ret i32 [[TZ]]82;83  %s = sext i16 %x to i3284  %tz = call i32 @llvm.cttz.i32(i32 %s, i1 false)85  ret i32 %tz86}87 88define i32 @cttz_sext_zero_undef_extra_use(i16 %x) {89; CHECK-LABEL: @cttz_sext_zero_undef_extra_use(90; CHECK-NEXT:    [[S:%.*]] = sext i16 [[X:%.*]] to i3291; CHECK-NEXT:    call void @use(i32 [[S]])92; CHECK-NEXT:    [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[S]], i1 true)93; CHECK-NEXT:    ret i32 [[TZ]]94;95  %s = sext i16 %x to i3296  call void @use(i32 %s)97  %tz = call i32 @llvm.cttz.i32(i32 %s, i1 true)98  ret i32 %tz99}100 101define <2 x i64> @cttz_sext_zero_undef_vec(<2 x i32> %x) {102; CHECK-LABEL: @cttz_sext_zero_undef_vec(103; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X:%.*]], i1 true)104; CHECK-NEXT:    [[TZ:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>105; CHECK-NEXT:    ret <2 x i64> [[TZ]]106;107  %s = sext <2 x i32> %x to <2 x i64>108  %tz = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %s, i1 true)109  ret <2 x i64> %tz110}111 112define <2 x i64> @cttz_sext_zero_def_vec(<2 x i32> %x) {113; CHECK-LABEL: @cttz_sext_zero_def_vec(114; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i32> [[X:%.*]] to <2 x i64>115; CHECK-NEXT:    [[TZ:%.*]] = call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[TMP1]], i1 false)116; CHECK-NEXT:    ret <2 x i64> [[TZ]]117;118  %s = sext <2 x i32> %x to <2 x i64>119  %tz = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %s, i1 false)120  ret <2 x i64> %tz121}122 123define i32 @cttz_of_lowest_set_bit(i32 %x) {124; CHECK-LABEL: @cttz_of_lowest_set_bit(125; CHECK-NEXT:    [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)126; CHECK-NEXT:    ret i32 [[TZ]]127;128  %sub = sub i32 0, %x129  %and = and i32 %sub, %x130  %tz = call i32 @llvm.cttz.i32(i32 %and, i1 false)131  ret i32 %tz132}133 134define i32 @cttz_of_lowest_set_bit_commuted(i32 %xx) {135; CHECK-LABEL: @cttz_of_lowest_set_bit_commuted(136; CHECK-NEXT:    [[X:%.*]] = udiv i32 42, [[XX:%.*]]137; CHECK-NEXT:    [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X]], i1 false)138; CHECK-NEXT:    ret i32 [[TZ]]139;140  %x = udiv i32 42, %xx ; thwart complexity-based canonicalization141  %sub = sub i32 0, %x142  %and = and i32 %x, %sub143  %tz = call i32 @llvm.cttz.i32(i32 %and, i1 false)144  ret i32 %tz145}146 147define i32 @cttz_of_lowest_set_bit_poison_flag(i32 %x) {148; CHECK-LABEL: @cttz_of_lowest_set_bit_poison_flag(149; CHECK-NEXT:    [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true)150; CHECK-NEXT:    ret i32 [[TZ]]151;152  %sub = sub i32 0, %x153  %and = and i32 %sub, %x154  %tz = call i32 @llvm.cttz.i32(i32 %and, i1 true)155  ret i32 %tz156}157 158define <2 x i64> @cttz_of_lowest_set_bit_vec(<2 x i64> %x) {159; CHECK-LABEL: @cttz_of_lowest_set_bit_vec(160; CHECK-NEXT:    [[TZ:%.*]] = call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[X:%.*]], i1 false)161; CHECK-NEXT:    ret <2 x i64> [[TZ]]162;163  %sub = sub <2 x i64> zeroinitializer, %x164  %and = and <2 x i64> %sub, %x165  %tz = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %and, i1 false)166  ret <2 x i64> %tz167}168 169define <2 x i64> @cttz_of_lowest_set_bit_vec_undef(<2 x i64> %x) {170; CHECK-LABEL: @cttz_of_lowest_set_bit_vec_undef(171; CHECK-NEXT:    [[TZ:%.*]] = call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[X:%.*]], i1 false)172; CHECK-NEXT:    ret <2 x i64> [[TZ]]173;174  %sub = sub <2 x i64> zeroinitializer, %x175  %and = and <2 x i64> %sub, %x176  %tz = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %and, i1 false)177  ret <2 x i64> %tz178}179 180define i32 @cttz_of_lowest_set_bit_wrong_const(i32 %x) {181; CHECK-LABEL: @cttz_of_lowest_set_bit_wrong_const(182; CHECK-NEXT:    [[SUB:%.*]] = sub i32 1, [[X:%.*]]183; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[X]]184; CHECK-NEXT:    [[TZ:%.*]] = call range(i32 1, 33) i32 @llvm.cttz.i32(i32 [[AND]], i1 false)185; CHECK-NEXT:    ret i32 [[TZ]]186;187  %sub = sub i32 1, %x188  %and = and i32 %sub, %x189  %tz = call i32 @llvm.cttz.i32(i32 %and, i1 false)190  ret i32 %tz191}192 193define i32 @cttz_of_lowest_set_bit_wrong_operand(i32 %x, i32 %y) {194; CHECK-LABEL: @cttz_of_lowest_set_bit_wrong_operand(195; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[Y:%.*]]196; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[SUB]]197; CHECK-NEXT:    [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[AND]], i1 false)198; CHECK-NEXT:    ret i32 [[TZ]]199;200  %sub = sub i32 0, %y201  %and = and i32 %sub, %x202  %tz = call i32 @llvm.cttz.i32(i32 %and, i1 false)203  ret i32 %tz204}205 206define i32 @cttz_of_lowest_set_bit_wrong_intrinsic(i32 %x) {207; CHECK-LABEL: @cttz_of_lowest_set_bit_wrong_intrinsic(208; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[X:%.*]]209; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[SUB]]210; CHECK-NEXT:    [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[AND]], i1 false)211; CHECK-NEXT:    ret i32 [[TZ]]212;213  %sub = sub i32 0, %x214  %and = and i32 %sub, %x215  %tz = call i32 @llvm.ctlz.i32(i32 %and, i1 false)216  ret i32 %tz217}218 219define i32 @cttz_of_power_of_two(i32 %x) {220; CHECK-LABEL: @cttz_of_power_of_two(221; CHECK-NEXT:    [[R:%.*]] = sub i32 32, [[X:%.*]]222; CHECK-NEXT:    ret i32 [[R]]223;224  %lshr = lshr i32 -1, %x225  %add = add i32 %lshr, 1226  %r = call i32 @llvm.cttz.i32(i32 %add, i1 false)227  ret i32 %r228}229 230define i32 @cttz_of_power_of_two_zero_poison(i32 %x) {231; CHECK-LABEL: @cttz_of_power_of_two_zero_poison(232; CHECK-NEXT:    [[R:%.*]] = sub i32 32, [[X:%.*]]233; CHECK-NEXT:    ret i32 [[R]]234;235  %lshr = lshr i32 -1, %x236  %add = add i32 %lshr, 1237  %r = call i32 @llvm.cttz.i32(i32 %add, i1 true)238  ret i32 %r239}240 241define i32 @cttz_of_power_of_two_wrong_intrinsic(i32 %x) {242; CHECK-LABEL: @cttz_of_power_of_two_wrong_intrinsic(243; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 -1, [[X:%.*]]244; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[LSHR]], 1245; CHECK-NEXT:    [[R:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[ADD]], i1 false)246; CHECK-NEXT:    ret i32 [[R]]247;248  %lshr = lshr i32 -1, %x249  %add = add i32 %lshr, 1250  %r = call i32 @llvm.ctlz.i32(i32 %add, i1 false)251  ret i32 %r252}253 254define i32 @cttz_of_power_of_two_wrong_constant_1(i32 %x) {255; CHECK-LABEL: @cttz_of_power_of_two_wrong_constant_1(256; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 -2, [[X:%.*]]257; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[LSHR]], 1258; CHECK-NEXT:    [[R:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[ADD]], i1 true)259; CHECK-NEXT:    ret i32 [[R]]260;261  %lshr = lshr i32 -2, %x262  %add = add i32 %lshr, 1263  %r = call i32 @llvm.cttz.i32(i32 %add, i1 false)264  ret i32 %r265}266 267define i32 @cttz_of_power_of_two_wrong_constant_2(i32 %x) {268; CHECK-LABEL: @cttz_of_power_of_two_wrong_constant_2(269; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 -1, [[X:%.*]]270; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[LSHR]], -1271; CHECK-NEXT:    [[R:%.*]] = call range(i32 1, 33) i32 @llvm.cttz.i32(i32 [[ADD]], i1 false)272; CHECK-NEXT:    ret i32 [[R]]273;274  %lshr = lshr i32 -1, %x275  %add = add i32 %lshr, -1276  %r = call i32 @llvm.cttz.i32(i32 %add, i1 false)277  ret i32 %r278}279 280define i16 @cttz_assume(i16 %x) {281; CHECK-LABEL: @cttz_assume(282; CHECK-NEXT:    [[ADD:%.*]] = add i16 [[X:%.*]], 1283; CHECK-NEXT:    [[COND0:%.*]] = icmp ult i16 [[ADD]], 10284; CHECK-NEXT:    call void @llvm.assume(i1 [[COND0]])285; CHECK-NEXT:    [[COND1:%.*]] = icmp ne i16 [[X]], 0286; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])287; CHECK-NEXT:    [[CTTZ:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X]], i1 true)288; CHECK-NEXT:    ret i16 [[CTTZ]]289;290  %add = add i16 %x, 1291  %cond0 = icmp ult i16 %add, 10292  call void @llvm.assume(i1 %cond0)293 294  %cond1 = icmp ne i16 %x, 0295  call void @llvm.assume(i1 %cond1)296 297  %cttz = call i16 @llvm.cttz.i16(i16 %x, i1 false)298  ret i16 %cttz299}300 301 302declare void @use.i8(i8)303define i8 @fold_ctz_log2(i8 %x) {304; CHECK-LABEL: @fold_ctz_log2(305; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 5)306; CHECK-NEXT:    ret i8 [[R]]307;308  %p2 = shl i8 1, %x309  %v = call i8 @llvm.umin(i8 %p2, i8 32)310  %r = call i8 @llvm.cttz(i8 %v, i1 false)311  ret i8 %r312}313 314define i9 @fold_ctz_log2_i9_okay(i9 %x) {315; CHECK-LABEL: @fold_ctz_log2_i9_okay(316; CHECK-NEXT:    [[R:%.*]] = call i9 @llvm.umin.i9(i9 [[X:%.*]], i9 5)317; CHECK-NEXT:    ret i9 [[R]]318;319  %p2 = shl i9 1, %x320  %v = call i9 @llvm.umin(i9 %p2, i9 32)321  %r = call i9 @llvm.cttz(i9 %v, i1 false)322  ret i9 %r323}324 325define i8 @fold_ctz_log2_maybe_z(i8 %x, i8 %y, i1 %c) {326; CHECK-LABEL: @fold_ctz_log2_maybe_z(327; CHECK-NEXT:    [[V:%.*]] = shl i8 2, [[V_V:%.*]]328; CHECK-NEXT:    [[P2_2:%.*]] = shl i8 4, [[Y:%.*]]329; CHECK-NEXT:    [[V1:%.*]] = select i1 [[C:%.*]], i8 [[V]], i8 [[P2_2]]330; CHECK-NEXT:    [[R:%.*]] = call range(i8 1, 9) i8 @llvm.cttz.i8(i8 [[V1]], i1 false)331; CHECK-NEXT:    ret i8 [[R]]332;333  %p2 = shl i8 2, %x334  %p2_2 = shl i8 4, %y335  %v = select i1 %c, i8 %p2, i8 %p2_2336  %r = call i8 @llvm.cttz(i8 %v, i1 false)337  ret i8 %r338}339 340define i8 @fold_ctz_log2_maybe_z_okay(i8 %x, i8 %y, i1 %c) {341; CHECK-LABEL: @fold_ctz_log2_maybe_z_okay(342; CHECK-NEXT:    [[X:%.*]] = add i8 [[X1:%.*]], 1343; CHECK-NEXT:    [[Y:%.*]] = add i8 [[Y1:%.*]], 2344; CHECK-NEXT:    [[V_V:%.*]] = select i1 [[C:%.*]], i8 [[X]], i8 [[Y]]345; CHECK-NEXT:    ret i8 [[V_V]]346;347  %p2 = shl i8 2, %x348  %p2_2 = shl i8 4, %y349  %v = select i1 %c, i8 %p2, i8 %p2_2350  %r = call i8 @llvm.cttz(i8 %v, i1 true)351  ret i8 %r352}353 354define i8 @fold_clz_log2(i8 %x) {355; CHECK-LABEL: @fold_clz_log2(356; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 5)357; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP1]], 7358; CHECK-NEXT:    ret i8 [[R]]359;360  %p2 = shl i8 1, %x361  %v = call i8 @llvm.umin(i8 %p2, i8 32)362  %r = call i8 @llvm.ctlz(i8 %v, i1 false)363  ret i8 %r364}365 366define i8 @fold_clz_log2_multiuse_fail(i8 %x) {367; CHECK-LABEL: @fold_clz_log2_multiuse_fail(368; CHECK-NEXT:    [[P2:%.*]] = shl nuw i8 2, [[X:%.*]]369; CHECK-NEXT:    [[V:%.*]] = call i8 @llvm.umin.i8(i8 [[P2]], i8 32)370; CHECK-NEXT:    call void @use.i8(i8 [[V]])371; CHECK-NEXT:    [[R:%.*]] = call range(i8 2, 9) i8 @llvm.ctlz.i8(i8 [[V]], i1 true)372; CHECK-NEXT:    ret i8 [[R]]373;374  %p2 = shl nuw i8 2, %x375  %v = call i8 @llvm.umin(i8 %p2, i8 32)376  call void @use.i8(i8 %v)377  %r = call i8 @llvm.ctlz(i8 %v, i1 true)378  ret i8 %r379}380 381 382define i9 @fold_clz_log2_i9(i9 %x) {383; CHECK-LABEL: @fold_clz_log2_i9(384; CHECK-NEXT:    [[TMP1:%.*]] = call i9 @llvm.umin.i9(i9 [[X:%.*]], i9 5)385; CHECK-NEXT:    [[R:%.*]] = sub nuw nsw i9 8, [[TMP1]]386; CHECK-NEXT:    ret i9 [[R]]387;388  %p2 = shl i9 1, %x389  %v = call i9 @llvm.umin(i9 %p2, i9 32)390  %r = call i9 @llvm.ctlz(i9 %v, i1 true)391  ret i9 %r392}393