1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -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: [[TMP4:%.*]] = zext i1 [[TMP2]] to i32 13; CHECK-NEXT: ret i32 [[TMP4]] 14; 15 %tmp = and i32 %arg, 1 16 %tmp1 = icmp eq i32 %tmp, 0 17 %tmp2 = lshr i32 %arg, 1 18 %tmp3 = and i32 %tmp2, 1 19 %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1 20 ret i32 %tmp4 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:%.*]], <i32 3, i32 3> 26; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 27; CHECK-NEXT: [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 28; CHECK-NEXT: ret <2 x i32> [[TMP4]] 29; 30 %tmp = and <2 x i32> %arg, <i32 1, i32 1> 31 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 32 %tmp2 = lshr <2 x i32> %arg, <i32 1, i32 1> 33 %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1> 34 %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1> 35 ret <2 x i32> %tmp4 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: [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 43; CHECK-NEXT: ret <2 x i32> [[TMP4]] 44; 45 %tmp = and <2 x i32> %arg, <i32 1, i32 4> ; mask is not splat 46 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 47 %tmp2 = lshr <2 x i32> %arg, <i32 1, i32 1> 48 %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1> 49 %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1> 50 ret <2 x i32> %tmp4 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: [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 58; CHECK-NEXT: ret <2 x i32> [[TMP4]] 59; 60 %tmp = and <2 x i32> %arg, <i32 1, i32 1> 61 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 62 %tmp2 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat 63 %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1> 64 %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1> 65 ret <2 x i32> %tmp4 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: [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 73; CHECK-NEXT: ret <2 x i32> [[TMP4]] 74; 75 %tmp = and <2 x i32> %arg, <i32 8, i32 1> ; mask is not splat 76 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 77 %tmp2 = lshr <2 x i32> %arg, <i32 2, i32 1> ; shift is not splat 78 %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1> 79 %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1> 80 ret <2 x i32> %tmp4 81} 82 83define <3 x i32> @and_lshr_and_vec_undef(<3 x i32> %arg) { 84; CHECK-LABEL: @and_lshr_and_vec_undef( 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: [[TMP4:%.*]] = zext <3 x i1> [[TMP2]] to <3 x i32> 88; CHECK-NEXT: ret <3 x i32> [[TMP4]] 89; 90 %tmp = and <3 x i32> %arg, <i32 1, i32 undef, i32 1> 91 %tmp1 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 92 %tmp2 = lshr <3 x i32> %arg, <i32 1, i32 undef, i32 1> 93 %tmp3 = and <3 x i32> %tmp2, <i32 1, i32 undef, i32 1> 94 ; The second element of %tmp4 is poison because it is (undef ? poison : undef). 95 %tmp4 = select <3 x i1> %tmp1, <3 x i32> %tmp3, <3 x i32> <i32 1, i32 undef, i32 1> 96 ret <3 x i32> %tmp4 97} 98 99define i32 @and_and(i32 %arg) { 100; CHECK-LABEL: @and_and( 101; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG:%.*]], 3 102; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0 103; CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 104; CHECK-NEXT: ret i32 [[TMP3]] 105; 106 %tmp = and i32 %arg, 2 107 %tmp1 = icmp eq i32 %tmp, 0 108 %tmp2 = and i32 %arg, 1 109 %tmp3 = select i1 %tmp1, i32 %tmp2, i32 1 110 ret i32 %tmp3 111} 112 113define <2 x i32> @and_and_splatvec(<2 x i32> %arg) { 114; CHECK-LABEL: @and_and_splatvec( 115; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 3> 116; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 117; CHECK-NEXT: [[TMP3:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 118; CHECK-NEXT: ret <2 x i32> [[TMP3]] 119; 120 %tmp = and <2 x i32> %arg, <i32 2, i32 2> 121 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 122 %tmp2 = and <2 x i32> %arg, <i32 1, i32 1> 123 %tmp3 = select <2 x i1> %tmp1, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 124 ret <2 x i32> %tmp3 125} 126 127define <2 x i32> @and_and_vec(<2 x i32> %arg) { 128; CHECK-LABEL: @and_and_vec( 129; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 7, i32 3> 130; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 131; CHECK-NEXT: [[TMP3:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 132; CHECK-NEXT: ret <2 x i32> [[TMP3]] 133; 134 %tmp = and <2 x i32> %arg, <i32 6, i32 2> ; mask is not splat 135 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 136 %tmp2 = and <2 x i32> %arg, <i32 1, i32 1> 137 %tmp3 = select <2 x i1> %tmp1, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 138 ret <2 x i32> %tmp3 139} 140 141define <3 x i32> @and_and_vec_undef(<3 x i32> %arg) { 142; CHECK-LABEL: @and_and_vec_undef( 143; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i32> [[ARG:%.*]], <i32 3, i32 -1, i32 3> 144; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <3 x i32> [[TMP1]], zeroinitializer 145; CHECK-NEXT: [[TMP3:%.*]] = zext <3 x i1> [[TMP2]] to <3 x i32> 146; CHECK-NEXT: ret <3 x i32> [[TMP3]] 147; 148 %tmp = and <3 x i32> %arg, <i32 2, i32 undef, i32 2> 149 %tmp1 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 150 %tmp2 = and <3 x i32> %arg, <i32 1, i32 undef, i32 1> 151 %tmp3 = select <3 x i1> %tmp1, <3 x i32> %tmp2, <3 x i32> <i32 1, i32 undef, i32 1> 152 ret <3 x i32> %tmp3 153} 154 155; ============================================================================ ; 156; Mask can be a variable, too. 157; ============================================================================ ; 158 159define i32 @f_var0(i32 %arg, i32 %arg1) { 160; CHECK-LABEL: @f_var0( 161; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 2 162; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]] 163; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 164; CHECK-NEXT: [[TMP5:%.*]] = zext i1 [[TMP3]] to i32 165; CHECK-NEXT: ret i32 [[TMP5]] 166; 167 %tmp = and i32 %arg, %arg1 168 %tmp2 = icmp eq i32 %tmp, 0 169 %tmp3 = lshr i32 %arg, 1 170 %tmp4 = and i32 %tmp3, 1 171 %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1 172 ret i32 %tmp5 173} 174 175; Should be exactly as the previous one 176define i32 @f_var0_commutative_and(i32 %arg, i32 %arg1) { 177; CHECK-LABEL: @f_var0_commutative_and( 178; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 2 179; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]] 180; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 181; CHECK-NEXT: [[TMP5:%.*]] = zext i1 [[TMP3]] to i32 182; CHECK-NEXT: ret i32 [[TMP5]] 183; 184 %tmp = and i32 %arg1, %arg ; in different order 185 %tmp2 = icmp eq i32 %tmp, 0 186 %tmp3 = lshr i32 %arg, 1 187 %tmp4 = and i32 %tmp3, 1 188 %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1 189 ret i32 %tmp5 190} 191 192define <2 x i32> @f_var0_splatvec(<2 x i32> %arg, <2 x i32> %arg1) { 193; CHECK-LABEL: @f_var0_splatvec( 194; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], <i32 2, i32 2> 195; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[ARG:%.*]] 196; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer 197; CHECK-NEXT: [[TMP5:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32> 198; CHECK-NEXT: ret <2 x i32> [[TMP5]] 199; 200 %tmp = and <2 x i32> %arg, %arg1 201 %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer 202 %tmp3 = lshr <2 x i32> %arg, <i32 1, i32 1> 203 %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1> 204 %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1> 205 ret <2 x i32> %tmp5 206} 207 208define <2 x i32> @f_var0_vec(<2 x i32> %arg, <2 x i32> %arg1) { 209; CHECK-LABEL: @f_var0_vec( 210; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], <i32 2, i32 4> 211; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[ARG:%.*]] 212; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer 213; CHECK-NEXT: [[TMP5:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32> 214; CHECK-NEXT: ret <2 x i32> [[TMP5]] 215; 216 %tmp = and <2 x i32> %arg, %arg1 217 %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer 218 %tmp3 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat 219 %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1> 220 %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1> 221 ret <2 x i32> %tmp5 222} 223 224define <3 x i32> @f_var0_vec_undef(<3 x i32> %arg, <3 x i32> %arg1) { 225; CHECK-LABEL: @f_var0_vec_undef( 226; CHECK-NEXT: [[TMP1:%.*]] = or <3 x i32> [[ARG1:%.*]], <i32 2, i32 poison, i32 2> 227; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[ARG:%.*]] 228; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer 229; CHECK-NEXT: [[TMP5:%.*]] = zext <3 x i1> [[TMP3]] to <3 x i32> 230; CHECK-NEXT: ret <3 x i32> [[TMP5]] 231; 232 %tmp = and <3 x i32> %arg, %arg1 233 %tmp2 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 234 %tmp3 = lshr <3 x i32> %arg, <i32 1, i32 undef, i32 1> 235 %tmp4 = and <3 x i32> %tmp3, <i32 1, i32 undef, i32 1> 236 ; The second element of %tmp5 is poison because it is (undef ? poison : undef). 237 %tmp5 = select <3 x i1> %tmp2, <3 x i32> %tmp4, <3 x i32> <i32 1, i32 undef, i32 1> 238 ret <3 x i32> %tmp5 239} 240 241define i32 @f_var1(i32 %arg, i32 %arg1) { 242; CHECK-LABEL: @f_var1( 243; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1 244; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]] 245; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 246; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 247; CHECK-NEXT: ret i32 [[TMP4]] 248; 249 %tmp = and i32 %arg, %arg1 250 %tmp2 = icmp eq i32 %tmp, 0 251 %tmp3 = and i32 %arg, 1 252 %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1 253 ret i32 %tmp4 254} 255 256; Should be exactly as the previous one 257define i32 @f_var1_commutative_and(i32 %arg, i32 %arg1) { 258; CHECK-LABEL: @f_var1_commutative_and( 259; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1 260; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]] 261; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 262; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 263; CHECK-NEXT: ret i32 [[TMP4]] 264; 265 %tmp = and i32 %arg1, %arg ; in different order 266 %tmp2 = icmp eq i32 %tmp, 0 267 %tmp3 = and i32 %arg, 1 268 %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1 269 ret i32 %tmp4 270} 271 272define <2 x i32> @f_var1_vec(<2 x i32> %arg, <2 x i32> %arg1) { 273; CHECK-LABEL: @f_var1_vec( 274; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], <i32 1, i32 1> 275; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[ARG:%.*]] 276; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer 277; CHECK-NEXT: [[TMP4:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32> 278; CHECK-NEXT: ret <2 x i32> [[TMP4]] 279; 280 %tmp = and <2 x i32> %arg, %arg1 281 %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer 282 %tmp3 = and <2 x i32> %arg, <i32 1, i32 1> 283 %tmp4 = select <2 x i1> %tmp2, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1> 284 ret <2 x i32> %tmp4 285} 286 287define <3 x i32> @f_var1_vec_undef(<3 x i32> %arg, <3 x i32> %arg1) { 288; CHECK-LABEL: @f_var1_vec_undef( 289; CHECK-NEXT: [[TMP1:%.*]] = or <3 x i32> [[ARG1:%.*]], <i32 1, i32 1, i32 1> 290; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[ARG:%.*]] 291; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer 292; CHECK-NEXT: [[TMP4:%.*]] = zext <3 x i1> [[TMP3]] to <3 x i32> 293; CHECK-NEXT: ret <3 x i32> [[TMP4]] 294; 295 %tmp = and <3 x i32> %arg, %arg1 296 %tmp2 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 297 %tmp3 = and <3 x i32> %arg, <i32 1, i32 undef, i32 1> 298 %tmp4 = select <3 x i1> %tmp2, <3 x i32> %tmp3, <3 x i32> <i32 1, i32 undef, i32 1> 299 ret <3 x i32> %tmp4 300} 301 302; ============================================================================ ; 303; Shift can be a variable, too. 304; ============================================================================ ; 305 306define i32 @f_var2(i32 %arg, i32 %arg1) { 307; CHECK-LABEL: @f_var2( 308; CHECK-NEXT: [[TMP1:%.*]] = shl i32 1, [[ARG1:%.*]] 309; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 1 310; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], [[ARG:%.*]] 311; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0 312; CHECK-NEXT: [[TMP5:%.*]] = zext i1 [[TMP4]] to i32 313; CHECK-NEXT: ret i32 [[TMP5]] 314; 315 %tmp = and i32 %arg, 1 316 %tmp2 = icmp eq i32 %tmp, 0 317 %tmp3 = lshr i32 %arg, %arg1 318 %tmp4 = and i32 %tmp3, 1 319 %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1 320 ret i32 %tmp5 321} 322 323define <2 x i32> @f_var2_splatvec(<2 x i32> %arg, <2 x i32> %arg1) { 324; CHECK-LABEL: @f_var2_splatvec( 325; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[ARG1:%.*]] 326; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i32> [[TMP1]], <i32 1, i32 1> 327; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i32> [[TMP2]], [[ARG:%.*]] 328; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <2 x i32> [[TMP3]], zeroinitializer 329; CHECK-NEXT: [[TMP5:%.*]] = zext <2 x i1> [[TMP4]] to <2 x i32> 330; CHECK-NEXT: ret <2 x i32> [[TMP5]] 331; 332 %tmp = and <2 x i32> %arg, <i32 1, i32 1> 333 %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer 334 %tmp3 = lshr <2 x i32> %arg, %arg1 335 %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1> 336 %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1> 337 ret <2 x i32> %tmp5 338} 339 340define <2 x i32> @f_var2_vec(<2 x i32> %arg, <2 x i32> %arg1) { 341; CHECK-LABEL: @f_var2_vec( 342; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[ARG1:%.*]] 343; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i32> [[TMP1]], <i32 2, i32 1> 344; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i32> [[TMP2]], [[ARG:%.*]] 345; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <2 x i32> [[TMP3]], zeroinitializer 346; CHECK-NEXT: [[TMP5:%.*]] = zext <2 x i1> [[TMP4]] to <2 x i32> 347; CHECK-NEXT: ret <2 x i32> [[TMP5]] 348; 349 %tmp = and <2 x i32> %arg, <i32 2, i32 1>; mask is not splat 350 %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer 351 %tmp3 = lshr <2 x i32> %arg, %arg1 352 %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1> 353 %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1> 354 ret <2 x i32> %tmp5 355} 356 357define <3 x i32> @f_var2_vec_undef(<3 x i32> %arg, <3 x i32> %arg1) { 358; CHECK-LABEL: @f_var2_vec_undef( 359; CHECK-NEXT: [[TMP1:%.*]] = shl <3 x i32> <i32 1, i32 1, i32 1>, [[ARG1:%.*]] 360; CHECK-NEXT: [[TMP2:%.*]] = or <3 x i32> [[TMP1]], <i32 1, i32 undef, i32 1> 361; CHECK-NEXT: [[TMP3:%.*]] = and <3 x i32> [[TMP2]], [[ARG:%.*]] 362; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <3 x i32> [[TMP3]], zeroinitializer 363; CHECK-NEXT: [[TMP5:%.*]] = zext <3 x i1> [[TMP4]] to <3 x i32> 364; CHECK-NEXT: ret <3 x i32> [[TMP5]] 365; 366 %tmp = and <3 x i32> %arg, <i32 1, i32 undef, i32 1> 367 %tmp2 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 368 %tmp3 = lshr <3 x i32> %arg, %arg1 369 %tmp4 = and <3 x i32> %tmp3, <i32 1, i32 undef, i32 1> 370 %tmp5 = select <3 x i1> %tmp2, <3 x i32> %tmp4, <3 x i32> <i32 1, i32 undef, i32 1> 371 ret <3 x i32> %tmp5 372} 373 374; ============================================================================ ; 375; The worst case: both Mask and Shift are variables 376; ============================================================================ ; 377 378define i32 @f_var3(i32 %arg, i32 %arg1, i32 %arg2) { 379; CHECK-LABEL: @f_var3( 380; CHECK-NEXT: [[TMP1:%.*]] = shl i32 1, [[ARG2:%.*]] 381; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[ARG1:%.*]] 382; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], [[ARG:%.*]] 383; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0 384; CHECK-NEXT: [[TMP6:%.*]] = zext i1 [[TMP4]] to i32 385; CHECK-NEXT: ret i32 [[TMP6]] 386; 387 %tmp = and i32 %arg, %arg1 388 %tmp3 = icmp eq i32 %tmp, 0 389 %tmp4 = lshr i32 %arg, %arg2 390 %tmp5 = and i32 %tmp4, 1 391 %tmp6 = select i1 %tmp3, i32 %tmp5, i32 1 392 ret i32 %tmp6 393} 394 395; Should be exactly as the previous one 396define i32 @f_var3_commutative_and(i32 %arg, i32 %arg1, i32 %arg2) { 397; CHECK-LABEL: @f_var3_commutative_and( 398; CHECK-NEXT: [[TMP1:%.*]] = shl i32 1, [[ARG2:%.*]] 399; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[ARG1:%.*]] 400; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], [[ARG:%.*]] 401; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0 402; CHECK-NEXT: [[TMP6:%.*]] = zext i1 [[TMP4]] to i32 403; CHECK-NEXT: ret i32 [[TMP6]] 404; 405 %tmp = and i32 %arg1, %arg ; in different order 406 %tmp3 = icmp eq i32 %tmp, 0 407 %tmp4 = lshr i32 %arg, %arg2 408 %tmp5 = and i32 %tmp4, 1 409 %tmp6 = select i1 %tmp3, i32 %tmp5, i32 1 410 ret i32 %tmp6 411} 412 413define <2 x i32> @f_var3_splatvec(<2 x i32> %arg, <2 x i32> %arg1, <2 x i32> %arg2) { 414; CHECK-LABEL: @f_var3_splatvec( 415; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[ARG2:%.*]] 416; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i32> [[TMP1]], [[ARG1:%.*]] 417; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i32> [[TMP2]], [[ARG:%.*]] 418; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <2 x i32> [[TMP3]], zeroinitializer 419; CHECK-NEXT: [[TMP6:%.*]] = zext <2 x i1> [[TMP4]] to <2 x i32> 420; CHECK-NEXT: ret <2 x i32> [[TMP6]] 421; 422 %tmp = and <2 x i32> %arg, %arg1 423 %tmp3 = icmp eq <2 x i32> %tmp, zeroinitializer 424 %tmp4 = lshr <2 x i32> %arg, %arg2 425 %tmp5 = and <2 x i32> %tmp4, <i32 1, i32 1> 426 %tmp6 = select <2 x i1> %tmp3, <2 x i32> %tmp5, <2 x i32> <i32 1, i32 1> 427 ret <2 x i32> %tmp6 428} 429 430define <3 x i32> @f_var3_vec_undef(<3 x i32> %arg, <3 x i32> %arg1, <3 x i32> %arg2) { 431; CHECK-LABEL: @f_var3_vec_undef( 432; CHECK-NEXT: [[TMP1:%.*]] = shl <3 x i32> <i32 1, i32 1, i32 1>, [[ARG2:%.*]] 433; CHECK-NEXT: [[TMP2:%.*]] = or <3 x i32> [[TMP1]], [[ARG1:%.*]] 434; CHECK-NEXT: [[TMP3:%.*]] = and <3 x i32> [[TMP2]], [[ARG:%.*]] 435; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <3 x i32> [[TMP3]], zeroinitializer 436; CHECK-NEXT: [[TMP6:%.*]] = zext <3 x i1> [[TMP4]] to <3 x i32> 437; CHECK-NEXT: ret <3 x i32> [[TMP6]] 438; 439 %tmp = and <3 x i32> %arg, %arg1 440 %tmp3 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 441 %tmp4 = lshr <3 x i32> %arg, %arg2 442 %tmp5 = and <3 x i32> %tmp4, <i32 1, i32 undef, i32 1> 443 %tmp6 = select <3 x i1> %tmp3, <3 x i32> %tmp5, <3 x i32> <i32 1, i32 undef, i32 1> 444 ret <3 x i32> %tmp6 445} 446 447; ============================================================================ ; 448; Negative tests. Should not be folded. 449; ============================================================================ ; 450 451; One use only. 452 453declare void @use32(i32) 454 455declare void @use1(i1) 456 457define i32 @n_var0_oneuse(i32 %arg, i32 %arg1, i32 %arg2) { 458; CHECK-LABEL: @n_var0_oneuse( 459; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]] 460; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP]], 0 461; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]] 462; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1 463; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[TMP3]], i32 [[TMP5]], i32 1 464; CHECK-NEXT: call void @use32(i32 [[TMP]]) 465; CHECK-NEXT: call void @use1(i1 [[TMP3]]) 466; CHECK-NEXT: call void @use32(i32 [[TMP4]]) 467; CHECK-NEXT: call void @use32(i32 [[TMP5]]) 468; CHECK-NEXT: ret i32 [[TMP6]] 469; 470 %tmp = and i32 %arg, %arg1 471 %tmp3 = icmp eq i32 %tmp, 0 472 %tmp4 = lshr i32 %arg, %arg2 473 %tmp5 = and i32 %tmp4, 1 474 %tmp6 = select i1 %tmp3, i32 %tmp5, i32 1 475 call void @use32(i32 %tmp) 476 call void @use1(i1 %tmp3) 477 call void @use32(i32 %tmp4) 478 call void @use32(i32 %tmp5) 479 ret i32 %tmp6 480} 481 482define i32 @n_var1_oneuse(i32 %arg, i32 %arg1) { 483; CHECK-LABEL: @n_var1_oneuse( 484; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]] 485; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP]], 0 486; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[ARG]], 1 487; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 1 488; CHECK-NEXT: call void @use32(i32 [[TMP]]) 489; CHECK-NEXT: call void @use1(i1 [[TMP2]]) 490; CHECK-NEXT: call void @use32(i32 [[TMP3]]) 491; CHECK-NEXT: ret i32 [[TMP4]] 492; 493 %tmp = and i32 %arg, %arg1 494 %tmp2 = icmp eq i32 %tmp, 0 495 %tmp3 = and i32 %arg, 1 496 %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1 497 call void @use32(i32 %tmp) 498 call void @use1(i1 %tmp2) 499 call void @use32(i32 %tmp3) 500 ret i32 %tmp4 501} 502 503; Different variables are used 504 505define i32 @n0(i32 %arg, i32 %arg1) { 506; CHECK-LABEL: @n0( 507; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 1 508; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP]], 0 509; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[ARG1:%.*]], 1 510; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 1 511; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32 [[TMP4]], i32 1 512; CHECK-NEXT: ret i32 [[TMP5]] 513; 514 %tmp = and i32 %arg, 1 515 %tmp2 = icmp eq i32 %tmp, 0 516 %tmp3 = lshr i32 %arg1, 1 ; works on %arg1 instead of %arg 517 %tmp4 = and i32 %tmp3, 1 518 %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1 519 ret i32 %tmp5 520} 521 522define i32 @n1(i32 %arg, i32 %arg1) { 523; CHECK-LABEL: @n1( 524; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 2 525; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP]], 0 526; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[ARG1:%.*]], 1 527; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 1 528; CHECK-NEXT: ret i32 [[TMP4]] 529; 530 %tmp = and i32 %arg, 2 531 %tmp2 = icmp eq i32 %tmp, 0 532 %tmp3 = and i32 %arg1, 1 ; works on %arg1 instead of %arg 533 %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1 534 ret i32 %tmp4 535} 536 537; False-value is not 1 538 539define i32 @n2(i32 %arg) { 540; CHECK-LABEL: @n2( 541; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 1 542; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 543; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[ARG]], 2 544; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 1 545; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 0 546; CHECK-NEXT: ret i32 [[TMP4]] 547; 548 %tmp = and i32 %arg, 1 549 %tmp1 = icmp eq i32 %tmp, 0 550 %tmp2 = lshr i32 %arg, 2 551 %tmp3 = and i32 %tmp2, 1 552 %tmp4 = select i1 %tmp1, i32 %tmp3, i32 0 ; 0 instead of 1 553 ret i32 %tmp4 554} 555 556define i32 @n3(i32 %arg) { 557; CHECK-LABEL: @n3( 558; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 2 559; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 560; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[ARG]], 1 561; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[TMP2]], i32 0 562; CHECK-NEXT: ret i32 [[TMP3]] 563; 564 %tmp = and i32 %arg, 2 565 %tmp1 = icmp eq i32 %tmp, 0 566 %tmp2 = and i32 %arg, 1 567 %tmp3 = select i1 %tmp1, i32 %tmp2, i32 0 ; 0 instead of 1 568 ret i32 %tmp3 569} 570 571; Mask of second and is not one 572 573define i32 @n4(i32 %arg) { 574; CHECK-LABEL: @n4( 575; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 1 576; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 577; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[ARG]], 2 578; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 2 579; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 1 580; CHECK-NEXT: ret i32 [[TMP4]] 581; 582 %tmp = and i32 %arg, 1 583 %tmp1 = icmp eq i32 %tmp, 0 584 %tmp2 = lshr i32 %arg, 2 585 %tmp3 = and i32 %tmp2, 2 ; 2 instead of 1 586 %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1 587 ret i32 %tmp4 588} 589 590define i32 @n5(i32 %arg) { 591; CHECK-LABEL: @n5( 592; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 2 593; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 594; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[ARG]], 2 595; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[TMP2]], i32 1 596; CHECK-NEXT: ret i32 [[TMP3]] 597; 598 %tmp = and i32 %arg, 2 599 %tmp1 = icmp eq i32 %tmp, 0 600 %tmp2 = and i32 %arg, 2 ; 2 instead of 1 601 %tmp3 = select i1 %tmp1, i32 %tmp2, i32 1 602 ret i32 %tmp3 603} 604 605; Wrong icmp pred 606 607define i32 @n6(i32 %arg) { 608; CHECK-LABEL: @n6( 609; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 1 610; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 611; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[ARG]], 2 612; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 1 613; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i32 1, i32 [[TMP3]] 614; CHECK-NEXT: ret i32 [[TMP4]] 615; 616 %tmp = and i32 %arg, 1 617 %tmp1 = icmp ne i32 %tmp, 0 ; ne, not eq 618 %tmp2 = lshr i32 %arg, 2 619 %tmp3 = and i32 %tmp2, 1 620 %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1 621 ret i32 %tmp4 622} 623 624define i32 @n7(i32 %arg) { 625; CHECK-LABEL: @n7( 626; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 2 627; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 628; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[ARG]], 1 629; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 1, i32 [[TMP2]] 630; CHECK-NEXT: ret i32 [[TMP3]] 631; 632 %tmp = and i32 %arg, 2 633 %tmp1 = icmp ne i32 %tmp, 0 ; ne, not eq 634 %tmp2 = and i32 %arg, 1 635 %tmp3 = select i1 %tmp1, i32 %tmp2, i32 1 636 ret i32 %tmp3 637} 638 639; icmp second operand is not zero 640 641define i32 @n8(i32 %arg) { 642; CHECK-LABEL: @n8( 643; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 1 644; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 645; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[ARG]], 2 646; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 1 647; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i32 1, i32 [[TMP3]] 648; CHECK-NEXT: ret i32 [[TMP4]] 649; 650 %tmp = and i32 %arg, 1 651 %tmp1 = icmp eq i32 %tmp, 1 652 %tmp2 = lshr i32 %arg, 2 653 %tmp3 = and i32 %tmp2, 1 654 %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1 655 ret i32 %tmp4 656} 657