brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.8 KiB · 4495e7f Raw
654 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; https://bugs.llvm.org/show_bug.cgi?id=369505 6; These all should be just and+icmp, there should be no select.7 8define i32 @and_lshr_and(i32 %arg) {9; CHECK-LABEL: @and_lshr_and(10; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 311; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 012; CHECK-NEXT:    [[T4:%.*]] = zext i1 [[TMP2]] to i3213; CHECK-NEXT:    ret i32 [[T4]]14;15  %t = and i32 %arg, 116  %t1 = icmp eq i32 %t, 017  %t2 = lshr i32 %arg, 118  %t3 = and i32 %t2, 119  %t4 = select i1 %t1, i32 %t3, i32 120  ret i32 %t421}22 23define <2 x i32> @and_lshr_and_splatvec(<2 x i32> %arg) {24; CHECK-LABEL: @and_lshr_and_splatvec(25; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], splat (i32 3)26; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer27; CHECK-NEXT:    [[T4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>28; CHECK-NEXT:    ret <2 x i32> [[T4]]29;30  %t = and <2 x i32> %arg, <i32 1, i32 1>31  %t1 = icmp eq <2 x i32> %t, zeroinitializer32  %t2 = lshr <2 x i32> %arg, <i32 1, i32 1>33  %t3 = and <2 x i32> %t2, <i32 1, i32 1>34  %t4 = select <2 x i1> %t1, <2 x i32> %t3, <2 x i32> <i32 1, i32 1>35  ret <2 x i32> %t436}37 38define <2 x i32> @and_lshr_and_vec_v0(<2 x i32> %arg) {39; CHECK-LABEL: @and_lshr_and_vec_v0(40; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 6>41; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer42; CHECK-NEXT:    [[T4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>43; CHECK-NEXT:    ret <2 x i32> [[T4]]44;45  %t = and <2 x i32> %arg, <i32 1, i32 4> ; mask is not splat46  %t1 = icmp eq <2 x i32> %t, zeroinitializer47  %t2 = lshr <2 x i32> %arg, <i32 1, i32 1>48  %t3 = and <2 x i32> %t2, <i32 1, i32 1>49  %t4 = select <2 x i1> %t1, <2 x i32> %t3, <2 x i32> <i32 1, i32 1>50  ret <2 x i32> %t451}52 53define <2 x i32> @and_lshr_and_vec_v1(<2 x i32> %arg) {54; CHECK-LABEL: @and_lshr_and_vec_v1(55; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 5>56; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer57; CHECK-NEXT:    [[T4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>58; CHECK-NEXT:    ret <2 x i32> [[T4]]59;60  %t = and <2 x i32> %arg, <i32 1, i32 1>61  %t1 = icmp eq <2 x i32> %t, zeroinitializer62  %t2 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat63  %t3 = and <2 x i32> %t2, <i32 1, i32 1>64  %t4 = select <2 x i1> %t1, <2 x i32> %t3, <2 x i32> <i32 1, i32 1>65  ret <2 x i32> %t466}67 68define <2 x i32> @and_lshr_and_vec_v2(<2 x i32> %arg) {69; CHECK-LABEL: @and_lshr_and_vec_v2(70; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 12, i32 3>71; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer72; CHECK-NEXT:    [[T4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>73; CHECK-NEXT:    ret <2 x i32> [[T4]]74;75  %t = and <2 x i32> %arg, <i32 8, i32 1> ; mask is not splat76  %t1 = icmp eq <2 x i32> %t, zeroinitializer77  %t2 = lshr <2 x i32> %arg, <i32 2, i32 1> ; shift is not splat78  %t3 = and <2 x i32> %t2, <i32 1, i32 1>79  %t4 = select <2 x i1> %t1, <2 x i32> %t3, <2 x i32> <i32 1, i32 1>80  ret <2 x i32> %t481}82 83define <3 x i32> @and_lshr_and_vec_poison(<3 x i32> %arg) {84; CHECK-LABEL: @and_lshr_and_vec_poison(85; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i32> [[ARG:%.*]], <i32 3, i32 poison, i32 3>86; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <3 x i32> [[TMP1]], zeroinitializer87; CHECK-NEXT:    [[T4:%.*]] = zext <3 x i1> [[TMP2]] to <3 x i32>88; CHECK-NEXT:    ret <3 x i32> [[T4]]89;90  %t = and <3 x i32> %arg, <i32 1, i32 poison, i32 1>91  %t1 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>92  %t2 = lshr <3 x i32> %arg, <i32 1, i32 poison, i32 1>93  %t3 = and <3 x i32> %t2, <i32 1, i32 poison, i32 1>94  %t4 = select <3 x i1> %t1, <3 x i32> %t3, <3 x i32> <i32 1, i32 poison, i32 1>95  ret <3 x i32> %t496}97 98define i32 @and_and(i32 %arg) {99; CHECK-LABEL: @and_and(100; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 3101; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0102; CHECK-NEXT:    [[T3:%.*]] = zext i1 [[TMP2]] to i32103; CHECK-NEXT:    ret i32 [[T3]]104;105  %t = and i32 %arg, 2106  %t1 = icmp eq i32 %t, 0107  %t2 = and i32 %arg, 1108  %t3 = select i1 %t1, i32 %t2, i32 1109  ret i32 %t3110}111 112define <2 x i32> @and_and_splatvec(<2 x i32> %arg) {113; CHECK-LABEL: @and_and_splatvec(114; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], splat (i32 3)115; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer116; CHECK-NEXT:    [[T3:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>117; CHECK-NEXT:    ret <2 x i32> [[T3]]118;119  %t = and <2 x i32> %arg, <i32 2, i32 2>120  %t1 = icmp eq <2 x i32> %t, zeroinitializer121  %t2 = and <2 x i32> %arg, <i32 1, i32 1>122  %t3 = select <2 x i1> %t1, <2 x i32> %t2, <2 x i32> <i32 1, i32 1>123  ret <2 x i32> %t3124}125 126define <2 x i32> @and_and_vec(<2 x i32> %arg) {127; CHECK-LABEL: @and_and_vec(128; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 7, i32 3>129; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer130; CHECK-NEXT:    [[T3:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>131; CHECK-NEXT:    ret <2 x i32> [[T3]]132;133  %t = and <2 x i32> %arg, <i32 6, i32 2> ; mask is not splat134  %t1 = icmp eq <2 x i32> %t, zeroinitializer135  %t2 = and <2 x i32> %arg, <i32 1, i32 1>136  %t3 = select <2 x i1> %t1, <2 x i32> %t2, <2 x i32> <i32 1, i32 1>137  ret <2 x i32> %t3138}139 140define <3 x i32> @and_and_vec_poison(<3 x i32> %arg) {141; CHECK-LABEL: @and_and_vec_poison(142; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i32> [[ARG:%.*]], <i32 3, i32 poison, i32 3>143; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <3 x i32> [[TMP1]], zeroinitializer144; CHECK-NEXT:    [[T3:%.*]] = zext <3 x i1> [[TMP2]] to <3 x i32>145; CHECK-NEXT:    ret <3 x i32> [[T3]]146;147  %t = and <3 x i32> %arg, <i32 2, i32 poison, i32 2>148  %t1 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>149  %t2 = and <3 x i32> %arg, <i32 1, i32 poison, i32 1>150  %t3 = select <3 x i1> %t1, <3 x i32> %t2, <3 x i32> <i32 1, i32 poison, i32 1>151  ret <3 x i32> %t3152}153 154; ============================================================================ ;155; Mask can be a variable, too.156; ============================================================================ ;157 158define i32 @f_var0(i32 %arg, i32 %arg1) {159; CHECK-LABEL: @f_var0(160; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 2161; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]]162; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0163; CHECK-NEXT:    [[T5:%.*]] = zext i1 [[TMP3]] to i32164; CHECK-NEXT:    ret i32 [[T5]]165;166  %t = and i32 %arg, %arg1167  %t2 = icmp eq i32 %t, 0168  %t3 = lshr i32 %arg, 1169  %t4 = and i32 %t3, 1170  %t5 = select i1 %t2, i32 %t4, i32 1171  ret i32 %t5172}173 174; Should be exactly as the previous one175define i32 @f_var0_commutative_and(i32 %arg, i32 %arg1) {176; CHECK-LABEL: @f_var0_commutative_and(177; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 2178; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]]179; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0180; CHECK-NEXT:    [[T5:%.*]] = zext i1 [[TMP3]] to i32181; CHECK-NEXT:    ret i32 [[T5]]182;183  %t = and i32 %arg1, %arg ; in different order184  %t2 = icmp eq i32 %t, 0185  %t3 = lshr i32 %arg, 1186  %t4 = and i32 %t3, 1187  %t5 = select i1 %t2, i32 %t4, i32 1188  ret i32 %t5189}190 191define <2 x i32> @f_var0_splatvec(<2 x i32> %arg, <2 x i32> %arg1) {192; CHECK-LABEL: @f_var0_splatvec(193; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], splat (i32 2)194; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[ARG:%.*]], [[TMP1]]195; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer196; CHECK-NEXT:    [[T5:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32>197; CHECK-NEXT:    ret <2 x i32> [[T5]]198;199  %t = and <2 x i32> %arg, %arg1200  %t2 = icmp eq <2 x i32> %t, zeroinitializer201  %t3 = lshr <2 x i32> %arg, <i32 1, i32 1>202  %t4 = and <2 x i32> %t3, <i32 1, i32 1>203  %t5 = select <2 x i1> %t2, <2 x i32> %t4, <2 x i32> <i32 1, i32 1>204  ret <2 x i32> %t5205}206 207define <2 x i32> @f_var0_vec(<2 x i32> %arg, <2 x i32> %arg1) {208; CHECK-LABEL: @f_var0_vec(209; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], <i32 2, i32 4>210; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[ARG:%.*]], [[TMP1]]211; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer212; CHECK-NEXT:    [[T5:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32>213; CHECK-NEXT:    ret <2 x i32> [[T5]]214;215  %t = and <2 x i32> %arg, %arg1216  %t2 = icmp eq <2 x i32> %t, zeroinitializer217  %t3 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat218  %t4 = and <2 x i32> %t3, <i32 1, i32 1>219  %t5 = select <2 x i1> %t2, <2 x i32> %t4, <2 x i32> <i32 1, i32 1>220  ret <2 x i32> %t5221}222 223define <3 x i32> @f_var0_vec_poison(<3 x i32> %arg, <3 x i32> %arg1) {224; CHECK-LABEL: @f_var0_vec_poison(225; CHECK-NEXT:    [[TMP1:%.*]] = or <3 x i32> [[ARG1:%.*]], <i32 2, i32 poison, i32 2>226; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[ARG:%.*]], [[TMP1]]227; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer228; CHECK-NEXT:    [[T5:%.*]] = zext <3 x i1> [[TMP3]] to <3 x i32>229; CHECK-NEXT:    ret <3 x i32> [[T5]]230;231  %t = and <3 x i32> %arg, %arg1232  %t2 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>233  %t3 = lshr <3 x i32> %arg, <i32 1, i32 poison, i32 1>234  %t4 = and <3 x i32> %t3, <i32 1, i32 poison, i32 1>235  ; The second element of %t5 is poison because it is (poison ? poison : poison).236  %t5 = select <3 x i1> %t2, <3 x i32> %t4, <3 x i32> <i32 1, i32 poison, i32 1>237  ret <3 x i32> %t5238}239 240define i32 @f_var1(i32 %arg, i32 %arg1) {241; CHECK-LABEL: @f_var1(242; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1243; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]]244; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0245; CHECK-NEXT:    [[T4:%.*]] = zext i1 [[TMP3]] to i32246; CHECK-NEXT:    ret i32 [[T4]]247;248  %t = and i32 %arg, %arg1249  %t2 = icmp eq i32 %t, 0250  %t3 = and i32 %arg, 1251  %t4 = select i1 %t2, i32 %t3, i32 1252  ret i32 %t4253}254 255; Should be exactly as the previous one256define i32 @f_var1_commutative_and(i32 %arg, i32 %arg1) {257; CHECK-LABEL: @f_var1_commutative_and(258; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1259; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]]260; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0261; CHECK-NEXT:    [[T4:%.*]] = zext i1 [[TMP3]] to i32262; CHECK-NEXT:    ret i32 [[T4]]263;264  %t = and i32 %arg1, %arg ; in different order265  %t2 = icmp eq i32 %t, 0266  %t3 = and i32 %arg, 1267  %t4 = select i1 %t2, i32 %t3, i32 1268  ret i32 %t4269}270 271define <2 x i32> @f_var1_vec(<2 x i32> %arg, <2 x i32> %arg1) {272; CHECK-LABEL: @f_var1_vec(273; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], splat (i32 1)274; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[ARG:%.*]], [[TMP1]]275; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer276; CHECK-NEXT:    [[T4:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32>277; CHECK-NEXT:    ret <2 x i32> [[T4]]278;279  %t = and <2 x i32> %arg, %arg1280  %t2 = icmp eq <2 x i32> %t, zeroinitializer281  %t3 = and <2 x i32> %arg, <i32 1, i32 1>282  %t4 = select <2 x i1> %t2, <2 x i32> %t3, <2 x i32> <i32 1, i32 1>283  ret <2 x i32> %t4284}285 286define <3 x i32> @f_var1_vec_poison(<3 x i32> %arg, <3 x i32> %arg1) {287; CHECK-LABEL: @f_var1_vec_poison(288; CHECK-NEXT:    [[TMP1:%.*]] = or <3 x i32> [[ARG1:%.*]], splat (i32 1)289; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[ARG:%.*]], [[TMP1]]290; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer291; CHECK-NEXT:    [[T4:%.*]] = zext <3 x i1> [[TMP3]] to <3 x i32>292; CHECK-NEXT:    ret <3 x i32> [[T4]]293;294  %t = and <3 x i32> %arg, %arg1295  %t2 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>296  %t3 = and <3 x i32> %arg, <i32 1, i32 poison, i32 1>297  %t4 = select <3 x i1> %t2, <3 x i32> %t3, <3 x i32> <i32 1, i32 poison, i32 1>298  ret <3 x i32> %t4299}300 301; ============================================================================ ;302; Shift can't be a variable in general.303; ============================================================================ ;304 305define i32 @f_var2(i32 %arg, i32 %arg1) {306; CHECK-LABEL: @f_var2(307; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1308; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T]], 0309; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[ARG]], [[ARG1:%.*]]310; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T3]], 1311; CHECK-NEXT:    [[T5:%.*]] = select i1 [[T2]], i32 [[T4]], i32 1312; CHECK-NEXT:    ret i32 [[T5]]313;314  %t = and i32 %arg, 1315  %t2 = icmp eq i32 %t, 0316  %t3 = lshr i32 %arg, %arg1317  %t4 = and i32 %t3, 1318  %t5 = select i1 %t2, i32 %t4, i32 1319  ret i32 %t5320}321 322define <2 x i32> @f_var2_splatvec(<2 x i32> %arg, <2 x i32> %arg1) {323; CHECK-LABEL: @f_var2_splatvec(324; CHECK-NEXT:    [[T:%.*]] = and <2 x i32> [[ARG:%.*]], splat (i32 1)325; CHECK-NEXT:    [[T2:%.*]] = icmp eq <2 x i32> [[T]], zeroinitializer326; CHECK-NEXT:    [[T3:%.*]] = lshr <2 x i32> [[ARG]], [[ARG1:%.*]]327; CHECK-NEXT:    [[T4:%.*]] = and <2 x i32> [[T3]], splat (i32 1)328; CHECK-NEXT:    [[T5:%.*]] = select <2 x i1> [[T2]], <2 x i32> [[T4]], <2 x i32> splat (i32 1)329; CHECK-NEXT:    ret <2 x i32> [[T5]]330;331  %t = and <2 x i32> %arg, <i32 1, i32 1>332  %t2 = icmp eq <2 x i32> %t, zeroinitializer333  %t3 = lshr <2 x i32> %arg, %arg1334  %t4 = and <2 x i32> %t3, <i32 1, i32 1>335  %t5 = select <2 x i1> %t2, <2 x i32> %t4, <2 x i32> <i32 1, i32 1>336  ret <2 x i32> %t5337}338 339define <2 x i32> @f_var2_vec(<2 x i32> %arg, <2 x i32> %arg1) {340; CHECK-LABEL: @f_var2_vec(341; CHECK-NEXT:    [[T:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 2, i32 1>342; CHECK-NEXT:    [[T2:%.*]] = icmp eq <2 x i32> [[T]], zeroinitializer343; CHECK-NEXT:    [[T3:%.*]] = lshr <2 x i32> [[ARG]], [[ARG1:%.*]]344; CHECK-NEXT:    [[T4:%.*]] = and <2 x i32> [[T3]], splat (i32 1)345; CHECK-NEXT:    [[T5:%.*]] = select <2 x i1> [[T2]], <2 x i32> [[T4]], <2 x i32> splat (i32 1)346; CHECK-NEXT:    ret <2 x i32> [[T5]]347;348  %t = and <2 x i32> %arg, <i32 2, i32 1>; mask is not splat349  %t2 = icmp eq <2 x i32> %t, zeroinitializer350  %t3 = lshr <2 x i32> %arg, %arg1351  %t4 = and <2 x i32> %t3, <i32 1, i32 1>352  %t5 = select <2 x i1> %t2, <2 x i32> %t4, <2 x i32> <i32 1, i32 1>353  ret <2 x i32> %t5354}355 356define <3 x i32> @f_var2_vec_poison(<3 x i32> %arg, <3 x i32> %arg1) {357; CHECK-LABEL: @f_var2_vec_poison(358; CHECK-NEXT:    [[T:%.*]] = and <3 x i32> [[ARG:%.*]], <i32 1, i32 poison, i32 1>359; CHECK-NEXT:    [[T2:%.*]] = icmp eq <3 x i32> [[T]], <i32 0, i32 poison, i32 0>360; CHECK-NEXT:    [[T3:%.*]] = lshr <3 x i32> [[ARG]], [[ARG1:%.*]]361; CHECK-NEXT:    [[T4:%.*]] = and <3 x i32> [[T3]], <i32 1, i32 poison, i32 1>362; CHECK-NEXT:    [[T5:%.*]] = select <3 x i1> [[T2]], <3 x i32> [[T4]], <3 x i32> <i32 1, i32 poison, i32 1>363; CHECK-NEXT:    ret <3 x i32> [[T5]]364;365  %t = and <3 x i32> %arg, <i32 1, i32 poison, i32 1>366  %t2 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>367  %t3 = lshr <3 x i32> %arg, %arg1368  %t4 = and <3 x i32> %t3, <i32 1, i32 poison, i32 1>369  %t5 = select <3 x i1> %t2, <3 x i32> %t4, <3 x i32> <i32 1, i32 poison, i32 1>370  ret <3 x i32> %t5371}372 373; ============================================================================ ;374; The worst case: both Mask and Shift are variables375; ============================================================================ ;376 377define i32 @f_var3(i32 %arg, i32 %arg1, i32 %arg2) {378; CHECK-LABEL: @f_var3(379; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]]380; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T]], 0381; CHECK-NEXT:    [[T4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]]382; CHECK-NEXT:    [[T5:%.*]] = and i32 [[T4]], 1383; CHECK-NEXT:    [[T6:%.*]] = select i1 [[T3]], i32 [[T5]], i32 1384; CHECK-NEXT:    ret i32 [[T6]]385;386  %t = and i32 %arg, %arg1387  %t3 = icmp eq i32 %t, 0388  %t4 = lshr i32 %arg, %arg2389  %t5 = and i32 %t4, 1390  %t6 = select i1 %t3, i32 %t5, i32 1391  ret i32 %t6392}393 394; Should be exactly as the previous one395define i32 @f_var3_commutative_and(i32 %arg, i32 %arg1, i32 %arg2) {396; CHECK-LABEL: @f_var3_commutative_and(397; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG1:%.*]], [[ARG:%.*]]398; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T]], 0399; CHECK-NEXT:    [[T4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]]400; CHECK-NEXT:    [[T5:%.*]] = and i32 [[T4]], 1401; CHECK-NEXT:    [[T6:%.*]] = select i1 [[T3]], i32 [[T5]], i32 1402; CHECK-NEXT:    ret i32 [[T6]]403;404  %t = and i32 %arg1, %arg ; in different order405  %t3 = icmp eq i32 %t, 0406  %t4 = lshr i32 %arg, %arg2407  %t5 = and i32 %t4, 1408  %t6 = select i1 %t3, i32 %t5, i32 1409  ret i32 %t6410}411 412define <2 x i32> @f_var3_splatvec(<2 x i32> %arg, <2 x i32> %arg1, <2 x i32> %arg2) {413; CHECK-LABEL: @f_var3_splatvec(414; CHECK-NEXT:    [[T:%.*]] = and <2 x i32> [[ARG:%.*]], [[ARG1:%.*]]415; CHECK-NEXT:    [[T3:%.*]] = icmp eq <2 x i32> [[T]], zeroinitializer416; CHECK-NEXT:    [[T4:%.*]] = lshr <2 x i32> [[ARG]], [[ARG2:%.*]]417; CHECK-NEXT:    [[T5:%.*]] = and <2 x i32> [[T4]], splat (i32 1)418; CHECK-NEXT:    [[T6:%.*]] = select <2 x i1> [[T3]], <2 x i32> [[T5]], <2 x i32> splat (i32 1)419; CHECK-NEXT:    ret <2 x i32> [[T6]]420;421  %t = and <2 x i32> %arg, %arg1422  %t3 = icmp eq <2 x i32> %t, zeroinitializer423  %t4 = lshr <2 x i32> %arg, %arg2424  %t5 = and <2 x i32> %t4, <i32 1, i32 1>425  %t6 = select <2 x i1> %t3, <2 x i32> %t5, <2 x i32> <i32 1, i32 1>426  ret <2 x i32> %t6427}428 429define <3 x i32> @f_var3_vec_poison(<3 x i32> %arg, <3 x i32> %arg1, <3 x i32> %arg2) {430; CHECK-LABEL: @f_var3_vec_poison(431; CHECK-NEXT:    [[T:%.*]] = and <3 x i32> [[ARG:%.*]], [[ARG1:%.*]]432; CHECK-NEXT:    [[T3:%.*]] = icmp eq <3 x i32> [[T]], <i32 0, i32 poison, i32 0>433; CHECK-NEXT:    [[T4:%.*]] = lshr <3 x i32> [[ARG]], [[ARG2:%.*]]434; CHECK-NEXT:    [[T5:%.*]] = and <3 x i32> [[T4]], <i32 1, i32 poison, i32 1>435; CHECK-NEXT:    [[T6:%.*]] = select <3 x i1> [[T3]], <3 x i32> [[T5]], <3 x i32> <i32 1, i32 poison, i32 1>436; CHECK-NEXT:    ret <3 x i32> [[T6]]437;438  %t = and <3 x i32> %arg, %arg1439  %t3 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>440  %t4 = lshr <3 x i32> %arg, %arg2441  %t5 = and <3 x i32> %t4, <i32 1, i32 poison, i32 1>442  %t6 = select <3 x i1> %t3, <3 x i32> %t5, <3 x i32> <i32 1, i32 poison, i32 1>443  ret <3 x i32> %t6444}445 446; ============================================================================ ;447; Negative tests. Should not be folded.448; ============================================================================ ;449 450; One use only.451 452declare void @use32(i32)453 454declare void @use1(i1)455 456define i32 @n_var0_oneuse(i32 %arg, i32 %arg1, i32 %arg2) {457; CHECK-LABEL: @n_var0_oneuse(458; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]]459; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T]], 0460; CHECK-NEXT:    [[T4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]]461; CHECK-NEXT:    [[T5:%.*]] = and i32 [[T4]], 1462; CHECK-NEXT:    [[T6:%.*]] = select i1 [[T3]], i32 [[T5]], i32 1463; CHECK-NEXT:    call void @use32(i32 [[T]])464; CHECK-NEXT:    call void @use1(i1 [[T3]])465; CHECK-NEXT:    call void @use32(i32 [[T4]])466; CHECK-NEXT:    call void @use32(i32 [[T5]])467; CHECK-NEXT:    ret i32 [[T6]]468;469  %t = and i32 %arg, %arg1470  %t3 = icmp eq i32 %t, 0471  %t4 = lshr i32 %arg, %arg2472  %t5 = and i32 %t4, 1473  %t6 = select i1 %t3, i32 %t5, i32 1474  call void @use32(i32 %t)475  call void @use1(i1 %t3)476  call void @use32(i32 %t4)477  call void @use32(i32 %t5)478  ret i32 %t6479}480 481define i32 @n_var1_oneuse(i32 %arg, i32 %arg1) {482; CHECK-LABEL: @n_var1_oneuse(483; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]]484; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T]], 0485; CHECK-NEXT:    [[T3:%.*]] = and i32 [[ARG]], 1486; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T2]], i32 [[T3]], i32 1487; CHECK-NEXT:    call void @use32(i32 [[T]])488; CHECK-NEXT:    call void @use1(i1 [[T2]])489; CHECK-NEXT:    call void @use32(i32 [[T3]])490; CHECK-NEXT:    ret i32 [[T4]]491;492  %t = and i32 %arg, %arg1493  %t2 = icmp eq i32 %t, 0494  %t3 = and i32 %arg, 1495  %t4 = select i1 %t2, i32 %t3, i32 1496  call void @use32(i32 %t)497  call void @use1(i1 %t2)498  call void @use32(i32 %t3)499  ret i32 %t4500}501 502; Different variables are used503 504define i32 @n0(i32 %arg, i32 %arg1) {505; CHECK-LABEL: @n0(506; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1507; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T]], 0508; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[ARG1:%.*]], 1509; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T3]], 1510; CHECK-NEXT:    [[T5:%.*]] = select i1 [[T2]], i32 [[T4]], i32 1511; CHECK-NEXT:    ret i32 [[T5]]512;513  %t = and i32 %arg, 1514  %t2 = icmp eq i32 %t, 0515  %t3 = lshr i32 %arg1, 1 ; works on %arg1 instead of %arg516  %t4 = and i32 %t3, 1517  %t5 = select i1 %t2, i32 %t4, i32 1518  ret i32 %t5519}520 521define i32 @n1(i32 %arg, i32 %arg1) {522; CHECK-LABEL: @n1(523; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 2524; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T]], 0525; CHECK-NEXT:    [[T3:%.*]] = and i32 [[ARG1:%.*]], 1526; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T2]], i32 [[T3]], i32 1527; CHECK-NEXT:    ret i32 [[T4]]528;529  %t = and i32 %arg, 2530  %t2 = icmp eq i32 %t, 0531  %t3 = and i32 %arg1, 1 ; works on %arg1 instead of %arg532  %t4 = select i1 %t2, i32 %t3, i32 1533  ret i32 %t4534}535 536; False-value is not 1537 538define i32 @n2(i32 %arg) {539; CHECK-LABEL: @n2(540; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1541; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[T]], 0542; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[ARG]], 2543; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T2]], 1544; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T1]], i32 [[T3]], i32 0545; CHECK-NEXT:    ret i32 [[T4]]546;547  %t = and i32 %arg, 1548  %t1 = icmp eq i32 %t, 0549  %t2 = lshr i32 %arg, 2550  %t3 = and i32 %t2, 1551  %t4 = select i1 %t1, i32 %t3, i32 0 ; 0 instead of 1552  ret i32 %t4553}554 555define i32 @n3(i32 %arg) {556; CHECK-LABEL: @n3(557; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 2558; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[T]], 0559; CHECK-NEXT:    [[T2:%.*]] = and i32 [[ARG]], 1560; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T1]], i32 [[T2]], i32 0561; CHECK-NEXT:    ret i32 [[T3]]562;563  %t = and i32 %arg, 2564  %t1 = icmp eq i32 %t, 0565  %t2 = and i32 %arg, 1566  %t3 = select i1 %t1, i32 %t2, i32 0 ; 0 instead of 1567  ret i32 %t3568}569 570; Mask of second and is not one571 572define i32 @n4(i32 %arg) {573; CHECK-LABEL: @n4(574; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1575; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[T]], 0576; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[ARG]], 2577; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T2]], 2578; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T1]], i32 [[T3]], i32 1579; CHECK-NEXT:    ret i32 [[T4]]580;581  %t = and i32 %arg, 1582  %t1 = icmp eq i32 %t, 0583  %t2 = lshr i32 %arg, 2584  %t3 = and i32 %t2, 2 ; 2 instead of 1585  %t4 = select i1 %t1, i32 %t3, i32 1586  ret i32 %t4587}588 589define i32 @n5(i32 %arg) {590; CHECK-LABEL: @n5(591; CHECK-NEXT:    [[T:%.*]] = lshr i32 [[ARG:%.*]], 1592; CHECK-NEXT:    [[T_LOBIT:%.*]] = and i32 [[T]], 1593; CHECK-NEXT:    ret i32 [[T_LOBIT]]594;595  %t = and i32 %arg, 2596  %t1 = icmp eq i32 %t, 0597  %t2 = and i32 %arg, 2 ; 2 instead of 1598  %t3 = select i1 %t1, i32 %t2, i32 1599  ret i32 %t3600}601 602; Wrong icmp pred603 604define i32 @n6(i32 %arg) {605; CHECK-LABEL: @n6(606; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1607; CHECK-NEXT:    [[T1_NOT:%.*]] = icmp eq i32 [[T]], 0608; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[ARG]], 2609; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T2]], 1610; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T1_NOT]], i32 1, i32 [[T3]]611; CHECK-NEXT:    ret i32 [[T4]]612;613  %t = and i32 %arg, 1614  %t1 = icmp ne i32 %t, 0 ; ne, not eq615  %t2 = lshr i32 %arg, 2616  %t3 = and i32 %t2, 1617  %t4 = select i1 %t1, i32 %t3, i32 1618  ret i32 %t4619}620 621define i32 @n7(i32 %arg) {622; CHECK-LABEL: @n7(623; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 2624; CHECK-NEXT:    [[T1_NOT:%.*]] = icmp eq i32 [[T]], 0625; CHECK-NEXT:    [[T2:%.*]] = and i32 [[ARG]], 1626; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T1_NOT]], i32 1, i32 [[T2]]627; CHECK-NEXT:    ret i32 [[T3]]628;629  %t = and i32 %arg, 2630  %t1 = icmp ne i32 %t, 0 ; ne, not eq631  %t2 = and i32 %arg, 1632  %t3 = select i1 %t1, i32 %t2, i32 1633  ret i32 %t3634}635 636; icmp second operand is not zero637 638define i32 @n8(i32 %arg) {639; CHECK-LABEL: @n8(640; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1641; CHECK-NEXT:    [[T1_NOT:%.*]] = icmp eq i32 [[T]], 0642; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[ARG]], 2643; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T2]], 1644; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T1_NOT]], i32 1, i32 [[T3]]645; CHECK-NEXT:    ret i32 [[T4]]646;647  %t = and i32 %arg, 1648  %t1 = icmp eq i32 %t, 1649  %t2 = lshr i32 %arg, 2650  %t3 = and i32 %t2, 1651  %t4 = select i1 %t1, i32 %t3, i32 1652  ret i32 %t4653}654