754 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(i8)5 6define i32 @icmp_eq_and_pow2_shl1(i32 %0) {7; CHECK-LABEL: @icmp_eq_and_pow2_shl1(8; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 49; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i3210; CHECK-NEXT: ret i32 [[CONV]]11;12 %shl = shl i32 1, %013 %and = and i32 %shl, 1614 %cmp = icmp eq i32 %and, 015 %conv = zext i1 %cmp to i3216 ret i32 %conv17}18 19define <2 x i32> @icmp_eq_and_pow2_shl1_vec(<2 x i32> %0) {20; CHECK-LABEL: @icmp_eq_and_pow2_shl1_vec(21; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP0:%.*]], splat (i32 4)22; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>23; CHECK-NEXT: ret <2 x i32> [[CONV]]24;25 %shl = shl <2 x i32> <i32 1, i32 1>, %026 %and = and <2 x i32> %shl, <i32 16, i32 16>27 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>28 %conv = zext <2 x i1> %cmp to <2 x i32>29 ret <2 x i32> %conv30}31 32define i32 @icmp_ne_and_pow2_shl1(i32 %0) {33; CHECK-LABEL: @icmp_ne_and_pow2_shl1(34; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 435; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i3236; CHECK-NEXT: ret i32 [[CONV]]37;38 %shl = shl i32 1, %039 %and = and i32 %shl, 1640 %cmp = icmp ne i32 %and, 041 %conv = zext i1 %cmp to i3242 ret i32 %conv43}44 45define <2 x i32> @icmp_ne_and_pow2_shl1_vec(<2 x i32> %0) {46; CHECK-LABEL: @icmp_ne_and_pow2_shl1_vec(47; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP0:%.*]], splat (i32 4)48; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>49; CHECK-NEXT: ret <2 x i32> [[CONV]]50;51 %shl = shl <2 x i32> <i32 1, i32 1>, %052 %and = and <2 x i32> %shl, <i32 16, i32 16>53 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>54 %conv = zext <2 x i1> %cmp to <2 x i32>55 ret <2 x i32> %conv56}57 58define i32 @icmp_eq_and_pow2_shl_pow2(i32 %0) {59; CHECK-LABEL: @icmp_eq_and_pow2_shl_pow2(60; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 361; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i3262; CHECK-NEXT: ret i32 [[CONV]]63;64 %shl = shl i32 2, %065 %and = and i32 %shl, 1666 %cmp = icmp eq i32 %and, 067 %conv = zext i1 %cmp to i3268 ret i32 %conv69}70 71define <2 x i32> @icmp_eq_and_pow2_shl_pow2_vec(<2 x i32> %0) {72; CHECK-LABEL: @icmp_eq_and_pow2_shl_pow2_vec(73; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP0:%.*]], splat (i32 2)74; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>75; CHECK-NEXT: ret <2 x i32> [[CONV]]76;77 %shl = shl <2 x i32> <i32 4, i32 4>, %078 %and = and <2 x i32> %shl, <i32 16, i32 16>79 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>80 %conv = zext <2 x i1> %cmp to <2 x i32>81 ret <2 x i32> %conv82}83 84define i32 @icmp_ne_and_pow2_shl_pow2(i32 %0) {85; CHECK-LABEL: @icmp_ne_and_pow2_shl_pow2(86; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 387; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i3288; CHECK-NEXT: ret i32 [[CONV]]89;90 %shl = shl i32 2, %091 %and = and i32 %shl, 1692 %cmp = icmp ne i32 %and, 093 %conv = zext i1 %cmp to i3294 ret i32 %conv95}96 97define <2 x i32> @icmp_ne_and_pow2_shl_pow2_vec(<2 x i32> %0) {98; CHECK-LABEL: @icmp_ne_and_pow2_shl_pow2_vec(99; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP0:%.*]], splat (i32 2)100; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>101; CHECK-NEXT: ret <2 x i32> [[CONV]]102;103 %shl = shl <2 x i32> <i32 4, i32 4>, %0104 %and = and <2 x i32> %shl, <i32 16, i32 16>105 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>106 %conv = zext <2 x i1> %cmp to <2 x i32>107 ret <2 x i32> %conv108}109 110define i32 @icmp_eq_and_pow2_shl_pow2_negative1(i32 %0) {111; CHECK-LABEL: @icmp_eq_and_pow2_shl_pow2_negative1(112; CHECK-NEXT: [[SHL:%.*]] = shl i32 11, [[TMP0:%.*]]113; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[SHL]], 4114; CHECK-NEXT: [[AND_LOBIT:%.*]] = and i32 [[AND]], 1115; CHECK-NEXT: [[CONV:%.*]] = xor i32 [[AND_LOBIT]], 1116; CHECK-NEXT: ret i32 [[CONV]]117;118 %shl = shl i32 11, %0119 %and = and i32 %shl, 16120 %cmp = icmp eq i32 %and, 0121 %conv = zext i1 %cmp to i32122 ret i32 %conv123}124 125define i32 @icmp_eq_and_pow2_shl_pow2_negative2(i32 %0) {126; CHECK-LABEL: @icmp_eq_and_pow2_shl_pow2_negative2(127; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0:%.*]], 2128; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32129; CHECK-NEXT: ret i32 [[CONV]]130;131 %shl = shl i32 2, %0132 %and = and i32 %shl, 14133 %cmp = icmp eq i32 %and, 0134 %conv = zext i1 %cmp to i32135 ret i32 %conv136}137 138define i32 @icmp_eq_and_pow2_shl_pow2_negative3(i32 %0) {139; CHECK-LABEL: @icmp_eq_and_pow2_shl_pow2_negative3(140; CHECK-NEXT: ret i32 1141;142 %shl = shl i32 32, %0143 %and = and i32 %shl, 16144 %cmp = icmp eq i32 %and, 0145 %conv = zext i1 %cmp to i32146 ret i32 %conv147}148 149 150define i32 @icmp_eq_and_pow2_minus1_shl1(i32 %0) {151; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl1(152; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0:%.*]], 3153; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32154; CHECK-NEXT: ret i32 [[CONV]]155;156 %shl = shl i32 1, %0157 %and = and i32 %shl, 15158 %cmp = icmp eq i32 %and, 0159 %conv = zext i1 %cmp to i32160 ret i32 %conv161}162 163define <2 x i32> @icmp_eq_and_pow2_minus1_shl1_vec(<2 x i32> %0) {164; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl1_vec(165; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[TMP0:%.*]], splat (i32 3)166; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>167; CHECK-NEXT: ret <2 x i32> [[CONV]]168;169 %shl = shl <2 x i32> <i32 1, i32 1>, %0170 %and = and <2 x i32> %shl, <i32 15, i32 15>171 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>172 %conv = zext <2 x i1> %cmp to <2 x i32>173 ret <2 x i32> %conv174}175 176define i32 @icmp_ne_and_pow2_minus1_shl1(i32 %0) {177; CHECK-LABEL: @icmp_ne_and_pow2_minus1_shl1(178; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP0:%.*]], 4179; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32180; CHECK-NEXT: ret i32 [[CONV]]181;182 %shl = shl i32 1, %0183 %and = and i32 %shl, 15184 %cmp = icmp ne i32 %and, 0185 %conv = zext i1 %cmp to i32186 ret i32 %conv187}188 189define <2 x i32> @icmp_ne_and_pow2_minus1_shl1_vec(<2 x i32> %0) {190; CHECK-LABEL: @icmp_ne_and_pow2_minus1_shl1_vec(191; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[TMP0:%.*]], splat (i32 4)192; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>193; CHECK-NEXT: ret <2 x i32> [[CONV]]194;195 %shl = shl <2 x i32> <i32 1, i32 1>, %0196 %and = and <2 x i32> %shl, <i32 15, i32 15>197 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>198 %conv = zext <2 x i1> %cmp to <2 x i32>199 ret <2 x i32> %conv200}201 202define i32 @icmp_eq_and_pow2_minus1_shl_pow2(i32 %0) {203; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl_pow2(204; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0:%.*]], 2205; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32206; CHECK-NEXT: ret i32 [[CONV]]207;208 %shl = shl i32 2, %0209 %and = and i32 %shl, 15210 %cmp = icmp eq i32 %and, 0211 %conv = zext i1 %cmp to i32212 ret i32 %conv213}214 215define <2 x i32> @icmp_eq_and_pow2_minus1_shl_pow2_vec(<2 x i32> %0) {216; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl_pow2_vec(217; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[TMP0:%.*]], splat (i32 1)218; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>219; CHECK-NEXT: ret <2 x i32> [[CONV]]220;221 %shl = shl <2 x i32> <i32 4, i32 4>, %0222 %and = and <2 x i32> %shl, <i32 15, i32 15>223 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>224 %conv = zext <2 x i1> %cmp to <2 x i32>225 ret <2 x i32> %conv226}227 228define i32 @icmp_ne_and_pow2_minus1_shl_pow2(i32 %0) {229; CHECK-LABEL: @icmp_ne_and_pow2_minus1_shl_pow2(230; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP0:%.*]], 3231; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32232; CHECK-NEXT: ret i32 [[CONV]]233;234 %shl = shl i32 2, %0235 %and = and i32 %shl, 15236 %cmp = icmp ne i32 %and, 0237 %conv = zext i1 %cmp to i32238 ret i32 %conv239}240 241define <2 x i32> @icmp_ne_and_pow2_minus1_shl_pow2_vec(<2 x i32> %0) {242; CHECK-LABEL: @icmp_ne_and_pow2_minus1_shl_pow2_vec(243; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[TMP0:%.*]], splat (i32 2)244; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>245; CHECK-NEXT: ret <2 x i32> [[CONV]]246;247 %shl = shl <2 x i32> <i32 4, i32 4>, %0248 %and = and <2 x i32> %shl, <i32 15, i32 15>249 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>250 %conv = zext <2 x i1> %cmp to <2 x i32>251 ret <2 x i32> %conv252}253 254define i32 @icmp_eq_and_pow2_minus1_shl1_negative1(i32 %0) {255; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl1_negative1(256; CHECK-NEXT: [[SHL:%.*]] = shl i32 3, [[TMP0:%.*]]257; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], 15258; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0259; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32260; CHECK-NEXT: ret i32 [[CONV]]261;262 %shl = shl i32 3, %0263 %and = and i32 %shl, 15264 %cmp = icmp eq i32 %and, 0265 %conv = zext i1 %cmp to i32266 ret i32 %conv267}268 269define i32 @icmp_eq_and_pow2_minus1_shl1_negative2(i32 %0) {270; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl1_negative2(271; CHECK-NEXT: ret i32 1272;273 %shl = shl i32 32, %0274 %and = and i32 %shl, 15275 %cmp = icmp eq i32 %and, 0276 %conv = zext i1 %cmp to i32277 ret i32 %conv278}279 280 281define i32 @icmp_eq_and1_lshr_pow2(i32 %0) {282; CHECK-LABEL: @icmp_eq_and1_lshr_pow2(283; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 3284; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32285; CHECK-NEXT: ret i32 [[CONV]]286;287 %lshr = lshr i32 8, %0288 %and = and i32 %lshr, 1289 %cmp = icmp eq i32 %and, 0290 %conv = zext i1 %cmp to i32291 ret i32 %conv292}293 294define <2 x i32> @icmp_eq_and1_lshr_pow2_vec(<2 x i32> %0) {295; CHECK-LABEL: @icmp_eq_and1_lshr_pow2_vec(296; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP0:%.*]], splat (i32 3)297; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>298; CHECK-NEXT: ret <2 x i32> [[CONV]]299;300 %lshr = lshr <2 x i32> <i32 8, i32 8>, %0301 %and = and <2 x i32> %lshr, <i32 1, i32 1>302 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>303 %conv = zext <2 x i1> %cmp to <2 x i32>304 ret <2 x i32> %conv305}306 307define i32 @icmp_ne_and1_lshr_pow2(i32 %0) {308; CHECK-LABEL: @icmp_ne_and1_lshr_pow2(309; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 3310; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32311; CHECK-NEXT: ret i32 [[CONV]]312;313 %lshr = lshr i32 8, %0314 %and = and i32 %lshr, 1315 %cmp = icmp eq i32 %and, 0316 %conv = zext i1 %cmp to i32317 ret i32 %conv318}319 320define <2 x i32> @icmp_ne_and1_lshr_pow2_vec(<2 x i32> %0) {321; CHECK-LABEL: @icmp_ne_and1_lshr_pow2_vec(322; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP0:%.*]], splat (i32 1)323; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>324; CHECK-NEXT: ret <2 x i32> [[CONV]]325;326 %lshr = lshr <2 x i32> <i32 8, i32 8>, %0327 %and = and <2 x i32> %lshr, <i32 4, i32 4>328 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>329 %conv = zext <2 x i1> %cmp to <2 x i32>330 ret <2 x i32> %conv331}332 333define i32 @icmp_eq_and_pow2_lshr_pow2(i32 %0) {334; CHECK-LABEL: @icmp_eq_and_pow2_lshr_pow2(335; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 1336; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32337; CHECK-NEXT: ret i32 [[CONV]]338;339 %lshr = lshr i32 8, %0340 %and = and i32 %lshr, 4341 %cmp = icmp eq i32 %and, 0342 %conv = zext i1 %cmp to i32343 ret i32 %conv344}345 346define i32 @icmp_eq_and_pow2_lshr_pow2_case2(i32 %0) {347; CHECK-LABEL: @icmp_eq_and_pow2_lshr_pow2_case2(348; CHECK-NEXT: ret i32 1349;350 %lshr = lshr i32 4, %0351 %and = and i32 %lshr, 8352 %cmp = icmp eq i32 %and, 0353 %conv = zext i1 %cmp to i32354 ret i32 %conv355}356 357define <2 x i32> @icmp_eq_and_pow2_lshr_pow2_vec(<2 x i32> %0) {358; CHECK-LABEL: @icmp_eq_and_pow2_lshr_pow2_vec(359; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP0:%.*]], splat (i32 1)360; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>361; CHECK-NEXT: ret <2 x i32> [[CONV]]362;363 %lshr = lshr <2 x i32> <i32 8, i32 8>, %0364 %and = and <2 x i32> %lshr, <i32 4, i32 4>365 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>366 %conv = zext <2 x i1> %cmp to <2 x i32>367 ret <2 x i32> %conv368}369 370define i32 @icmp_ne_and_pow2_lshr_pow2(i32 %0) {371; CHECK-LABEL: @icmp_ne_and_pow2_lshr_pow2(372; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 1373; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32374; CHECK-NEXT: ret i32 [[CONV]]375;376 %lshr = lshr i32 8, %0377 %and = and i32 %lshr, 4378 %cmp = icmp eq i32 %and, 0379 %conv = zext i1 %cmp to i32380 ret i32 %conv381}382 383define i32 @icmp_ne_and_pow2_lshr_pow2_case2(i32 %0) {384; CHECK-LABEL: @icmp_ne_and_pow2_lshr_pow2_case2(385; CHECK-NEXT: ret i32 1386;387 %lshr = lshr i32 4, %0388 %and = and i32 %lshr, 8389 %cmp = icmp eq i32 %and, 0390 %conv = zext i1 %cmp to i32391 ret i32 %conv392}393 394define <2 x i32> @icmp_ne_and_pow2_lshr_pow2_vec(<2 x i32> %0) {395; CHECK-LABEL: @icmp_ne_and_pow2_lshr_pow2_vec(396; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP0:%.*]], splat (i32 1)397; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>398; CHECK-NEXT: ret <2 x i32> [[CONV]]399;400 %lshr = lshr <2 x i32> <i32 8, i32 8>, %0401 %and = and <2 x i32> %lshr, <i32 4, i32 4>402 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>403 %conv = zext <2 x i1> %cmp to <2 x i32>404 ret <2 x i32> %conv405}406 407define i32 @icmp_eq_and1_lshr_pow2_minus_one(i32 %0) {408; CHECK-LABEL: @icmp_eq_and1_lshr_pow2_minus_one(409; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0:%.*]], 2410; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32411; CHECK-NEXT: ret i32 [[CONV]]412;413 %lshr = lshr i32 7, %0414 %and = and i32 %lshr, 1415 %cmp = icmp eq i32 %and, 0416 %conv = zext i1 %cmp to i32417 ret i32 %conv418}419 420define i32 @icmp_eq_and1_lshr_pow2_negative2(i32 %0) {421; CHECK-LABEL: @icmp_eq_and1_lshr_pow2_negative2(422; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 8, [[TMP0:%.*]]423; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], 3424; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0425; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32426; CHECK-NEXT: ret i32 [[CONV]]427;428 %lshr = lshr i32 8, %0429 %and = and i32 %lshr, 3430 %cmp = icmp eq i32 %and, 0431 %conv = zext i1 %cmp to i32432 ret i32 %conv433}434 435define i1 @eq_and_shl_one(i8 %x, i8 %y) {436; CHECK-LABEL: @eq_and_shl_one(437; CHECK-NEXT: [[POW2:%.*]] = shl nuw i8 1, [[Y:%.*]]438; CHECK-NEXT: [[AND:%.*]] = and i8 [[POW2]], [[X:%.*]]439; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0440; CHECK-NEXT: ret i1 [[CMP]]441;442 %pow2 = shl i8 1, %y443 %and = and i8 %pow2, %x444 %cmp = icmp eq i8 %and, %pow2445 ret i1 %cmp446}447 448define <2 x i1> @ne_and_shl_one_commute(<2 x i8> %x, <2 x i8> %y) {449; CHECK-LABEL: @ne_and_shl_one_commute(450; CHECK-NEXT: [[POW2:%.*]] = shl nuw <2 x i8> <i8 1, i8 poison>, [[Y:%.*]]451; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[POW2]], [[X:%.*]]452; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer453; CHECK-NEXT: ret <2 x i1> [[CMP]]454;455 %pow2 = shl <2 x i8> <i8 1, i8 poison>, %y456 %and = and <2 x i8> %pow2, %x457 %cmp = icmp ne <2 x i8> %pow2, %and458 ret <2 x i1> %cmp459}460 461define i1 @ne_and_lshr_minval(i8 %px, i8 %y) {462; CHECK-LABEL: @ne_and_lshr_minval(463; CHECK-NEXT: [[X:%.*]] = mul i8 [[PX:%.*]], [[PX]]464; CHECK-NEXT: [[POW2:%.*]] = lshr exact i8 -128, [[Y:%.*]]465; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[POW2]]466; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0467; CHECK-NEXT: ret i1 [[CMP]]468;469 %x = mul i8 %px, %px ; thwart complexity-based canonicalization470 %pow2 = lshr i8 -128, %y471 %and = and i8 %x, %pow2472 %cmp = icmp ne i8 %and, %pow2473 ret i1 %cmp474}475 476define i1 @eq_and_lshr_minval_commute(i8 %px, i8 %y) {477; CHECK-LABEL: @eq_and_lshr_minval_commute(478; CHECK-NEXT: [[X:%.*]] = mul i8 [[PX:%.*]], [[PX]]479; CHECK-NEXT: [[POW2:%.*]] = lshr exact i8 -128, [[Y:%.*]]480; CHECK-NEXT: call void @use(i8 [[POW2]])481; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[POW2]]482; CHECK-NEXT: call void @use(i8 [[AND]])483; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0484; CHECK-NEXT: ret i1 [[CMP]]485;486 %x = mul i8 %px, %px ; thwart complexity-based canonicalization487 %pow2 = lshr i8 -128, %y488 call void @use(i8 %pow2)489 %and = and i8 %x, %pow2490 call void @use(i8 %and)491 %cmp = icmp eq i8 %pow2, %and492 ret i1 %cmp493}494 495; Negative test: May be power of two or zero.496define i1 @eq_and_shl_two(i8 %x, i8 %y) {497; CHECK-LABEL: @eq_and_shl_two(498; CHECK-NEXT: [[POW2_OR_ZERO:%.*]] = shl i8 2, [[Y:%.*]]499; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[POW2_OR_ZERO]]500; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], [[POW2_OR_ZERO]]501; CHECK-NEXT: ret i1 [[CMP]]502;503 %pow2_or_zero = shl i8 2, %y504 %and = and i8 %x, %pow2_or_zero505 %cmp = icmp eq i8 %and, %pow2_or_zero506 ret i1 %cmp507}508 509; Negative test: Wrong predicate.510define i1 @slt_and_shl_one(i8 %x, i8 %y) {511; CHECK-LABEL: @slt_and_shl_one(512; CHECK-NEXT: [[POW2:%.*]] = shl nuw i8 1, [[Y:%.*]]513; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[POW2]]514; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[AND]], [[POW2]]515; CHECK-NEXT: ret i1 [[CMP]]516;517 %pow2 = shl i8 1, %y518 %and = and i8 %x, %pow2519 %cmp = icmp slt i8 %and, %pow2520 ret i1 %cmp521}522 523define i1 @fold_eq_lhs(i8 %x, i8 %y) {524; CHECK-LABEL: @fold_eq_lhs(525; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[Y:%.*]], [[X:%.*]]526; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], 0527; CHECK-NEXT: ret i1 [[R]]528;529 %shl = shl i8 -1, %x530 %and = and i8 %shl, %y531 %r = icmp eq i8 %and, 0532 ret i1 %r533}534 535define i1 @fold_eq_lhs_fail_eq_nonzero(i8 %x, i8 %y) {536; CHECK-LABEL: @fold_eq_lhs_fail_eq_nonzero(537; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -1, [[X:%.*]]538; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHL]], [[Y:%.*]]539; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 1540; CHECK-NEXT: ret i1 [[R]]541;542 %shl = shl i8 -1, %x543 %and = and i8 %shl, %y544 %r = icmp eq i8 %and, 1545 ret i1 %r546}547 548define i1 @fold_eq_lhs_fail_multiuse_shl(i8 %x, i8 %y) {549; CHECK-LABEL: @fold_eq_lhs_fail_multiuse_shl(550; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -1, [[X:%.*]]551; CHECK-NEXT: call void @use(i8 [[SHL]])552; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHL]], [[Y:%.*]]553; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 0554; CHECK-NEXT: ret i1 [[R]]555;556 %shl = shl i8 -1, %x557 call void @use(i8 %shl)558 %and = and i8 %shl, %y559 %r = icmp eq i8 %and, 0560 ret i1 %r561}562 563define i1 @fold_ne_rhs(i8 %x, i8 %yy) {564; CHECK-LABEL: @fold_ne_rhs(565; CHECK-NEXT: [[Y:%.*]] = xor i8 [[YY:%.*]], 123566; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[Y]], [[X:%.*]]567; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[TMP1]], 0568; CHECK-NEXT: ret i1 [[R]]569;570 %y = xor i8 %yy, 123571 %shl = shl i8 -1, %x572 %and = and i8 %y, %shl573 %r = icmp ne i8 %and, 0574 ret i1 %r575}576 577define i1 @fold_ne_rhs_fail_multiuse_and(i8 %x, i8 %yy) {578; CHECK-LABEL: @fold_ne_rhs_fail_multiuse_and(579; CHECK-NEXT: [[Y:%.*]] = xor i8 [[YY:%.*]], 123580; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -1, [[X:%.*]]581; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[SHL]]582; CHECK-NEXT: call void @use(i8 [[AND]])583; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], 0584; CHECK-NEXT: ret i1 [[R]]585;586 %y = xor i8 %yy, 123587 %shl = shl i8 -1, %x588 %and = and i8 %y, %shl589 call void @use(i8 %and)590 %r = icmp ne i8 %and, 0591 ret i1 %r592}593 594define i1 @fold_ne_rhs_fail_shift_not_1s(i8 %x, i8 %yy) {595; CHECK-LABEL: @fold_ne_rhs_fail_shift_not_1s(596; CHECK-NEXT: [[Y:%.*]] = xor i8 [[YY:%.*]], 122597; CHECK-NEXT: [[SHL:%.*]] = shl i8 -2, [[X:%.*]]598; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[SHL]]599; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], 0600; CHECK-NEXT: ret i1 [[R]]601;602 %y = xor i8 %yy, 123603 %shl = shl i8 -2, %x604 %and = and i8 %y, %shl605 %r = icmp ne i8 %and, 0606 ret i1 %r607}608 609define i1 @test_shr_and_1_ne_0(i32 %a, i32 %b) {610; CHECK-LABEL: @test_shr_and_1_ne_0(611; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]612; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[A:%.*]], [[TMP1]]613; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0614; CHECK-NEXT: ret i1 [[CMP]]615;616 %shr = lshr i32 %a, %b617 %and = and i32 %shr, 1618 %cmp = icmp ne i32 %and, 0619 ret i1 %cmp620}621 622define i1 @test_shr_and_1_ne_0_samesign(i32 %a, i32 %b) {623; CHECK-LABEL: @test_shr_and_1_ne_0_samesign(624; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]625; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[A:%.*]], [[TMP1]]626; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0627; CHECK-NEXT: ret i1 [[CMP]]628;629 %shr = lshr i32 %a, %b630 %and = and i32 %shr, 1631 %cmp = icmp samesign ne i32 %and, 0632 ret i1 %cmp633}634 635define i1 @test_const_shr_and_1_ne_0(i32 %b) {636; CHECK-LABEL: @test_const_shr_and_1_ne_0(637; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]638; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 42639; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0640; CHECK-NEXT: ret i1 [[CMP]]641;642 %shr = lshr i32 42, %b643 %and = and i32 %shr, 1644 %cmp = icmp ne i32 %and, 0645 ret i1 %cmp646}647 648define i1 @test_not_const_shr_and_1_ne_0(i32 %b) {649; CHECK-LABEL: @test_not_const_shr_and_1_ne_0(650; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]651; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 42652; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP2]], 0653; CHECK-NEXT: ret i1 [[CMP]]654;655 %shr = lshr i32 42, %b656 %and = and i32 %shr, 1657 %cmp = icmp eq i32 %and, 0658 ret i1 %cmp659}660 661define i1 @test_const_shr_exact_and_1_ne_0(i32 %b) {662; CHECK-LABEL: @test_const_shr_exact_and_1_ne_0(663; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]664; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 42665; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0666; CHECK-NEXT: ret i1 [[CMP]]667;668 %shr = lshr exact i32 42, %b669 %and = and i32 %shr, 1670 %cmp = icmp ne i32 %and, 0671 ret i1 %cmp672}673 674define i1 @test_const_shr_and_2_ne_0_negative(i32 %b) {675; CHECK-LABEL: @test_const_shr_and_2_ne_0_negative(676; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]677; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 2678; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0679; CHECK-NEXT: ret i1 [[CMP]]680;681 %shr = lshr i32 42, %b682 %and = and i32 %shr, 2683 %cmp = icmp eq i32 %and, 0684 ret i1 %cmp685}686 687define <8 x i1> @test_const_shr_and_1_ne_0_v8i8_splat_negative(<8 x i8> %b) {688; CHECK-LABEL: @test_const_shr_and_1_ne_0_v8i8_splat_negative(689; CHECK-NEXT: [[SHR:%.*]] = lshr <8 x i8> splat (i8 42), [[B:%.*]]690; CHECK-NEXT: [[CMP:%.*]] = trunc <8 x i8> [[SHR]] to <8 x i1>691; CHECK-NEXT: ret <8 x i1> [[CMP]]692;693 %shr = lshr <8 x i8> <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>, %b694 %and = and <8 x i8> %shr, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>695 %cmp = icmp ne <8 x i8> %and, zeroinitializer696 ret <8 x i1> %cmp697}698 699define <8 x i1> @test_const_shr_and_1_ne_0_v8i8_nonsplat_negative(<8 x i8> %b) {700; CHECK-LABEL: @test_const_shr_and_1_ne_0_v8i8_nonsplat_negative(701; CHECK-NEXT: [[SHR:%.*]] = lshr <8 x i8> <i8 42, i8 43, i8 44, i8 45, i8 46, i8 47, i8 48, i8 49>, [[B:%.*]]702; CHECK-NEXT: [[CMP:%.*]] = trunc <8 x i8> [[SHR]] to <8 x i1>703; CHECK-NEXT: ret <8 x i1> [[CMP]]704;705 %shr = lshr <8 x i8> <i8 42, i8 43, i8 44, i8 45, i8 46, i8 47, i8 48, i8 49>, %b706 %and = and <8 x i8> %shr, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>707 %cmp = icmp ne <8 x i8> %and, zeroinitializer708 ret <8 x i1> %cmp709}710 711define i1 @test_const_shr_and_1_ne_0_i1_negative(i1 %b) {712; CHECK-LABEL: @test_const_shr_and_1_ne_0_i1_negative(713; CHECK-NEXT: ret i1 true714;715 %shr = lshr i1 1, %b716 %and = and i1 %shr, 1717 %cmp = icmp ne i1 %and, 0718 ret i1 %cmp719}720 721define i1 @test_const_shr_and_1_ne_0_multi_use_lshr_negative(i32 %b) {722; CHECK-LABEL: @test_const_shr_and_1_ne_0_multi_use_lshr_negative(723; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]724; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 1725; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND]], 0726; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[B]], [[SHR]]727; CHECK-NEXT: [[RET:%.*]] = and i1 [[CMP1]], [[CMP2]]728; CHECK-NEXT: ret i1 [[RET]]729;730 %shr = lshr i32 42, %b731 %and = and i32 %shr, 1732 %cmp1 = icmp ne i32 %and, 0733 %cmp2 = icmp eq i32 %b, %shr734 %ret = and i1 %cmp1, %cmp2735 ret i1 %ret736}737 738define i1 @test_const_shr_and_1_ne_0_multi_use_and_negative(i32 %b) {739; CHECK-LABEL: @test_const_shr_and_1_ne_0_multi_use_and_negative(740; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]741; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 1742; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND]], 0743; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[B]], [[AND]]744; CHECK-NEXT: [[RET:%.*]] = and i1 [[CMP1]], [[CMP2]]745; CHECK-NEXT: ret i1 [[RET]]746;747 %shr = lshr i32 42, %b748 %and = and i32 %shr, 1749 %cmp1 = icmp ne i32 %and, 0750 %cmp2 = icmp eq i32 %b, %and751 %ret = and i1 %cmp1, %cmp2752 ret i1 %ret753}754