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