1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4; https://bugs.llvm.org/show_bug.cgi?id=36950 5 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:%.*]], 3 11; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0 12; CHECK-NEXT: [[T4:%.*]] = zext i1 [[TMP2]] to i32 13; CHECK-NEXT: ret i32 [[T4]] 14; 15 %t = and i32 %arg, 1 16 %t1 = icmp eq i32 %t, 0 17 %t2 = lshr i32 %arg, 1 18 %t3 = and i32 %t2, 1 19 %t4 = select i1 %t1, i32 %t3, i32 1 20 ret i32 %t4 21} 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]], zeroinitializer 27; 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, zeroinitializer 32 %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> %t4 36} 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]], zeroinitializer 42; 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 splat 46 %t1 = icmp eq <2 x i32> %t, zeroinitializer 47 %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> %t4 51} 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]], zeroinitializer 57; 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, zeroinitializer 62 %t2 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat 63 %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> %t4 66} 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]], zeroinitializer 72; 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 splat 76 %t1 = icmp eq <2 x i32> %t, zeroinitializer 77 %t2 = lshr <2 x i32> %arg, <i32 2, i32 1> ; shift is not splat 78 %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> %t4 81} 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]], zeroinitializer 87; 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> %t4 96} 97 98define i32 @and_and(i32 %arg) { 99; CHECK-LABEL: @and_and( 100; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG:%.*]], 3 101; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0 102; CHECK-NEXT: [[T3:%.*]] = zext i1 [[TMP2]] to i32 103; CHECK-NEXT: ret i32 [[T3]] 104; 105 %t = and i32 %arg, 2 106 %t1 = icmp eq i32 %t, 0 107 %t2 = and i32 %arg, 1 108 %t3 = select i1 %t1, i32 %t2, i32 1 109 ret i32 %t3 110} 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]], zeroinitializer 116; 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, zeroinitializer 121 %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> %t3 124} 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]], zeroinitializer 130; 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 splat 134 %t1 = icmp eq <2 x i32> %t, zeroinitializer 135 %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> %t3 138} 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]], zeroinitializer 144; 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> %t3 152} 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:%.*]], 2 161; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]] 162; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 163; CHECK-NEXT: [[T5:%.*]] = zext i1 [[TMP3]] to i32 164; CHECK-NEXT: ret i32 [[T5]] 165; 166 %t = and i32 %arg, %arg1 167 %t2 = icmp eq i32 %t, 0 168 %t3 = lshr i32 %arg, 1 169 %t4 = and i32 %t3, 1 170 %t5 = select i1 %t2, i32 %t4, i32 1 171 ret i32 %t5 172} 173 174; Should be exactly as the previous one 175define i32 @f_var0_commutative_and(i32 %arg, i32 %arg1) { 176; CHECK-LABEL: @f_var0_commutative_and( 177; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 2 178; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]] 179; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 180; CHECK-NEXT: [[T5:%.*]] = zext i1 [[TMP3]] to i32 181; CHECK-NEXT: ret i32 [[T5]] 182; 183 %t = and i32 %arg1, %arg ; in different order 184 %t2 = icmp eq i32 %t, 0 185 %t3 = lshr i32 %arg, 1 186 %t4 = and i32 %t3, 1 187 %t5 = select i1 %t2, i32 %t4, i32 1 188 ret i32 %t5 189} 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]], zeroinitializer 196; 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, %arg1 200 %t2 = icmp eq <2 x i32> %t, zeroinitializer 201 %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> %t5 205} 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]], zeroinitializer 212; 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, %arg1 216 %t2 = icmp eq <2 x i32> %t, zeroinitializer 217 %t3 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat 218 %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> %t5 221} 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]], zeroinitializer 228; 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, %arg1 232 %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> %t5 238} 239 240define i32 @f_var1(i32 %arg, i32 %arg1) { 241; CHECK-LABEL: @f_var1( 242; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1 243; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]] 244; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 245; CHECK-NEXT: [[T4:%.*]] = zext i1 [[TMP3]] to i32 246; CHECK-NEXT: ret i32 [[T4]] 247; 248 %t = and i32 %arg, %arg1 249 %t2 = icmp eq i32 %t, 0 250 %t3 = and i32 %arg, 1 251 %t4 = select i1 %t2, i32 %t3, i32 1 252 ret i32 %t4 253} 254 255; Should be exactly as the previous one 256define i32 @f_var1_commutative_and(i32 %arg, i32 %arg1) { 257; CHECK-LABEL: @f_var1_commutative_and( 258; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1 259; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]] 260; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 261; CHECK-NEXT: [[T4:%.*]] = zext i1 [[TMP3]] to i32 262; CHECK-NEXT: ret i32 [[T4]] 263; 264 %t = and i32 %arg1, %arg ; in different order 265 %t2 = icmp eq i32 %t, 0 266 %t3 = and i32 %arg, 1 267 %t4 = select i1 %t2, i32 %t3, i32 1 268 ret i32 %t4 269} 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]], zeroinitializer 276; 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, %arg1 280 %t2 = icmp eq <2 x i32> %t, zeroinitializer 281 %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> %t4 284} 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]], zeroinitializer 291; 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, %arg1 295 %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> %t4 299} 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:%.*]], 1 308; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T]], 0 309; CHECK-NEXT: [[T3:%.*]] = lshr i32 [[ARG]], [[ARG1:%.*]] 310; CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], 1 311; CHECK-NEXT: [[T5:%.*]] = select i1 [[T2]], i32 [[T4]], i32 1 312; CHECK-NEXT: ret i32 [[T5]] 313; 314 %t = and i32 %arg, 1 315 %t2 = icmp eq i32 %t, 0 316 %t3 = lshr i32 %arg, %arg1 317 %t4 = and i32 %t3, 1 318 %t5 = select i1 %t2, i32 %t4, i32 1 319 ret i32 %t5 320} 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]], zeroinitializer 326; 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, zeroinitializer 333 %t3 = lshr <2 x i32> %arg, %arg1 334 %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> %t5 337} 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]], zeroinitializer 343; 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 splat 349 %t2 = icmp eq <2 x i32> %t, zeroinitializer 350 %t3 = lshr <2 x i32> %arg, %arg1 351 %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> %t5 354} 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, %arg1 368 %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> %t5 371} 372 373; ============================================================================ ; 374; The worst case: both Mask and Shift are variables 375; ============================================================================ ; 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]], 0 381; CHECK-NEXT: [[T4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]] 382; CHECK-NEXT: [[T5:%.*]] = and i32 [[T4]], 1 383; CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 [[T5]], i32 1 384; CHECK-NEXT: ret i32 [[T6]] 385; 386 %t = and i32 %arg, %arg1 387 %t3 = icmp eq i32 %t, 0 388 %t4 = lshr i32 %arg, %arg2 389 %t5 = and i32 %t4, 1 390 %t6 = select i1 %t3, i32 %t5, i32 1 391 ret i32 %t6 392} 393 394; Should be exactly as the previous one 395define 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]], 0 399; CHECK-NEXT: [[T4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]] 400; CHECK-NEXT: [[T5:%.*]] = and i32 [[T4]], 1 401; CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 [[T5]], i32 1 402; CHECK-NEXT: ret i32 [[T6]] 403; 404 %t = and i32 %arg1, %arg ; in different order 405 %t3 = icmp eq i32 %t, 0 406 %t4 = lshr i32 %arg, %arg2 407 %t5 = and i32 %t4, 1 408 %t6 = select i1 %t3, i32 %t5, i32 1 409 ret i32 %t6 410} 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]], zeroinitializer 416; 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, %arg1 422 %t3 = icmp eq <2 x i32> %t, zeroinitializer 423 %t4 = lshr <2 x i32> %arg, %arg2 424 %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> %t6 427} 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, %arg1 439 %t3 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0> 440 %t4 = lshr <3 x i32> %arg, %arg2 441 %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> %t6 444} 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]], 0 460; CHECK-NEXT: [[T4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]] 461; CHECK-NEXT: [[T5:%.*]] = and i32 [[T4]], 1 462; CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 [[T5]], i32 1 463; 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, %arg1 470 %t3 = icmp eq i32 %t, 0 471 %t4 = lshr i32 %arg, %arg2 472 %t5 = and i32 %t4, 1 473 %t6 = select i1 %t3, i32 %t5, i32 1 474 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 %t6 479} 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]], 0 485; CHECK-NEXT: [[T3:%.*]] = and i32 [[ARG]], 1 486; CHECK-NEXT: [[T4:%.*]] = select i1 [[T2]], i32 [[T3]], i32 1 487; 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, %arg1 493 %t2 = icmp eq i32 %t, 0 494 %t3 = and i32 %arg, 1 495 %t4 = select i1 %t2, i32 %t3, i32 1 496 call void @use32(i32 %t) 497 call void @use1(i1 %t2) 498 call void @use32(i32 %t3) 499 ret i32 %t4 500} 501 502; Different variables are used 503 504define i32 @n0(i32 %arg, i32 %arg1) { 505; CHECK-LABEL: @n0( 506; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 1 507; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T]], 0 508; CHECK-NEXT: [[T3:%.*]] = lshr i32 [[ARG1:%.*]], 1 509; CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], 1 510; CHECK-NEXT: [[T5:%.*]] = select i1 [[T2]], i32 [[T4]], i32 1 511; CHECK-NEXT: ret i32 [[T5]] 512; 513 %t = and i32 %arg, 1 514 %t2 = icmp eq i32 %t, 0 515 %t3 = lshr i32 %arg1, 1 ; works on %arg1 instead of %arg 516 %t4 = and i32 %t3, 1 517 %t5 = select i1 %t2, i32 %t4, i32 1 518 ret i32 %t5 519} 520 521define i32 @n1(i32 %arg, i32 %arg1) { 522; CHECK-LABEL: @n1( 523; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 2 524; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T]], 0 525; CHECK-NEXT: [[T3:%.*]] = and i32 [[ARG1:%.*]], 1 526; CHECK-NEXT: [[T4:%.*]] = select i1 [[T2]], i32 [[T3]], i32 1 527; CHECK-NEXT: ret i32 [[T4]] 528; 529 %t = and i32 %arg, 2 530 %t2 = icmp eq i32 %t, 0 531 %t3 = and i32 %arg1, 1 ; works on %arg1 instead of %arg 532 %t4 = select i1 %t2, i32 %t3, i32 1 533 ret i32 %t4 534} 535 536; False-value is not 1 537 538define i32 @n2(i32 %arg) { 539; CHECK-LABEL: @n2( 540; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 1 541; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[T]], 0 542; CHECK-NEXT: [[T2:%.*]] = lshr i32 [[ARG]], 2 543; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], 1 544; CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 [[T3]], i32 0 545; CHECK-NEXT: ret i32 [[T4]] 546; 547 %t = and i32 %arg, 1 548 %t1 = icmp eq i32 %t, 0 549 %t2 = lshr i32 %arg, 2 550 %t3 = and i32 %t2, 1 551 %t4 = select i1 %t1, i32 %t3, i32 0 ; 0 instead of 1 552 ret i32 %t4 553} 554 555define i32 @n3(i32 %arg) { 556; CHECK-LABEL: @n3( 557; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 2 558; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[T]], 0 559; CHECK-NEXT: [[T2:%.*]] = and i32 [[ARG]], 1 560; CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 [[T2]], i32 0 561; CHECK-NEXT: ret i32 [[T3]] 562; 563 %t = and i32 %arg, 2 564 %t1 = icmp eq i32 %t, 0 565 %t2 = and i32 %arg, 1 566 %t3 = select i1 %t1, i32 %t2, i32 0 ; 0 instead of 1 567 ret i32 %t3 568} 569 570; Mask of second and is not one 571 572define i32 @n4(i32 %arg) { 573; CHECK-LABEL: @n4( 574; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 1 575; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[T]], 0 576; CHECK-NEXT: [[T2:%.*]] = lshr i32 [[ARG]], 2 577; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], 2 578; CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 [[T3]], i32 1 579; CHECK-NEXT: ret i32 [[T4]] 580; 581 %t = and i32 %arg, 1 582 %t1 = icmp eq i32 %t, 0 583 %t2 = lshr i32 %arg, 2 584 %t3 = and i32 %t2, 2 ; 2 instead of 1 585 %t4 = select i1 %t1, i32 %t3, i32 1 586 ret i32 %t4 587} 588 589define i32 @n5(i32 %arg) { 590; CHECK-LABEL: @n5( 591; CHECK-NEXT: [[T:%.*]] = lshr i32 [[ARG:%.*]], 1 592; CHECK-NEXT: [[T_LOBIT:%.*]] = and i32 [[T]], 1 593; CHECK-NEXT: ret i32 [[T_LOBIT]] 594; 595 %t = and i32 %arg, 2 596 %t1 = icmp eq i32 %t, 0 597 %t2 = and i32 %arg, 2 ; 2 instead of 1 598 %t3 = select i1 %t1, i32 %t2, i32 1 599 ret i32 %t3 600} 601 602; Wrong icmp pred 603 604define i32 @n6(i32 %arg) { 605; CHECK-LABEL: @n6( 606; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 1 607; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i32 [[T]], 0 608; CHECK-NEXT: [[T2:%.*]] = lshr i32 [[ARG]], 2 609; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], 1 610; CHECK-NEXT: [[T4:%.*]] = select i1 [[T1_NOT]], i32 1, i32 [[T3]] 611; CHECK-NEXT: ret i32 [[T4]] 612; 613 %t = and i32 %arg, 1 614 %t1 = icmp ne i32 %t, 0 ; ne, not eq 615 %t2 = lshr i32 %arg, 2 616 %t3 = and i32 %t2, 1 617 %t4 = select i1 %t1, i32 %t3, i32 1 618 ret i32 %t4 619} 620 621define i32 @n7(i32 %arg) { 622; CHECK-LABEL: @n7( 623; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 2 624; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i32 [[T]], 0 625; CHECK-NEXT: [[T2:%.*]] = and i32 [[ARG]], 1 626; CHECK-NEXT: [[T3:%.*]] = select i1 [[T1_NOT]], i32 1, i32 [[T2]] 627; CHECK-NEXT: ret i32 [[T3]] 628; 629 %t = and i32 %arg, 2 630 %t1 = icmp ne i32 %t, 0 ; ne, not eq 631 %t2 = and i32 %arg, 1 632 %t3 = select i1 %t1, i32 %t2, i32 1 633 ret i32 %t3 634} 635 636; icmp second operand is not zero 637 638define i32 @n8(i32 %arg) { 639; CHECK-LABEL: @n8( 640; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 1 641; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i32 [[T]], 0 642; CHECK-NEXT: [[T2:%.*]] = lshr i32 [[ARG]], 2 643; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], 1 644; CHECK-NEXT: [[T4:%.*]] = select i1 [[T1_NOT]], i32 1, i32 [[T3]] 645; CHECK-NEXT: ret i32 [[T4]] 646; 647 %t = and i32 %arg, 1 648 %t1 = icmp eq i32 %t, 1 649 %t2 = lshr i32 %arg, 2 650 %t3 = and i32 %t2, 1 651 %t4 = select i1 %t1, i32 %t3, i32 1 652 ret i32 %t4 653} 654