295 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 i1 @mul_mask_pow2_eq0(i8 %x) {7; CHECK-LABEL: @mul_mask_pow2_eq0(8; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 19; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 010; CHECK-NEXT: ret i1 [[CMP]]11;12 %mul = mul i8 %x, 4413 %and = and i8 %mul, 414 %cmp = icmp eq i8 %and, 015 ret i1 %cmp16}17 18; TODO: Demanded bits does not convert the mul to shift,19; but the 'and' could be of 'x' directly.20 21define i1 @mul_mask_pow2_ne0_use1(i8 %x) {22; CHECK-LABEL: @mul_mask_pow2_ne0_use1(23; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 4024; CHECK-NEXT: call void @use(i8 [[MUL]])25; CHECK-NEXT: [[AND:%.*]] = and i8 [[MUL]], 826; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 027; CHECK-NEXT: ret i1 [[CMP]]28;29 %mul = mul i8 %x, 4030 call void @use(i8 %mul)31 %and = and i8 %mul, 832 %cmp = icmp ne i8 %and, 033 ret i1 %cmp34}35 36; negative test - extra use of 'and' would require more instructions37 38define i1 @mul_mask_pow2_ne0_use2(i8 %x) {39; CHECK-LABEL: @mul_mask_pow2_ne0_use2(40; CHECK-NEXT: [[MUL:%.*]] = shl i8 [[X:%.*]], 341; CHECK-NEXT: [[AND:%.*]] = and i8 [[MUL]], 842; CHECK-NEXT: call void @use(i8 [[AND]])43; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 044; CHECK-NEXT: ret i1 [[CMP]]45;46 %mul = mul i8 %x, 4047 %and = and i8 %mul, 848 call void @use(i8 %and)49 %cmp = icmp ne i8 %and, 050 ret i1 %cmp51}52 53; non-equality predicates are converted to equality54 55define i1 @mul_mask_pow2_sgt0(i8 %x) {56; CHECK-LABEL: @mul_mask_pow2_sgt0(57; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 158; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 059; CHECK-NEXT: ret i1 [[CMP]]60;61 %mul = mul i8 %x, 4462 %and = and i8 %mul, 463 %cmp = icmp sgt i8 %and, 064 ret i1 %cmp65}66 67; unnecessary mask bits are removed68 69define i1 @mul_mask_fakepow2_ne0(i8 %x) {70; CHECK-LABEL: @mul_mask_fakepow2_ne0(71; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 172; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 073; CHECK-NEXT: ret i1 [[CMP]]74;75 %mul = mul i8 %x, 4476 %and = and i8 %mul, 577 %cmp = icmp ne i8 %and, 078 ret i1 %cmp79}80 81; non-zero cmp constant is converted82 83define i1 @mul_mask_pow2_eq4(i8 %x) {84; CHECK-LABEL: @mul_mask_pow2_eq4(85; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 186; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 087; CHECK-NEXT: ret i1 [[CMP]]88;89 %mul = mul i8 %x, 4490 %and = and i8 %mul, 491 %cmp = icmp eq i8 %and, 492 ret i1 %cmp93}94 95; negative test - must be pow2 mask constant96 97define i1 @mul_mask_notpow2_ne(i8 %x) {98; CHECK-LABEL: @mul_mask_notpow2_ne(99; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 12100; CHECK-NEXT: [[AND:%.*]] = and i8 [[MUL]], 12101; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0102; CHECK-NEXT: ret i1 [[CMP]]103;104 %mul = mul i8 %x, 60105 %and = and i8 %mul, 12106 %cmp = icmp ne i8 %and, 0107 ret i1 %cmp108}109 110define i1 @pr40493(i32 %area) {111; CHECK-LABEL: @pr40493(112; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AREA:%.*]], 1113; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0114; CHECK-NEXT: ret i1 [[CMP]]115;116 %mul = mul i32 %area, 12117 %rem = and i32 %mul, 4118 %cmp = icmp eq i32 %rem, 0119 ret i1 %cmp120}121 122define i1 @pr40493_neg1(i32 %area) {123; CHECK-LABEL: @pr40493_neg1(124; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[AREA:%.*]], 3125; CHECK-NEXT: [[REM:%.*]] = and i32 [[MUL]], 4126; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM]], 0127; CHECK-NEXT: ret i1 [[CMP]]128;129 %mul = mul i32 %area, 11130 %rem = and i32 %mul, 4131 %cmp = icmp eq i32 %rem, 0132 ret i1 %cmp133}134 135define i1 @pr40493_neg2(i32 %area) {136; CHECK-LABEL: @pr40493_neg2(137; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[AREA:%.*]], 12138; CHECK-NEXT: [[REM:%.*]] = and i32 [[MUL]], 12139; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM]], 0140; CHECK-NEXT: ret i1 [[CMP]]141;142 %mul = mul i32 %area, 12143 %rem = and i32 %mul, 15144 %cmp = icmp eq i32 %rem, 0145 ret i1 %cmp146}147 148define i32 @pr40493_neg3(i32 %area) {149; CHECK-LABEL: @pr40493_neg3(150; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[AREA:%.*]], 2151; CHECK-NEXT: [[REM:%.*]] = and i32 [[MUL]], 4152; CHECK-NEXT: ret i32 [[REM]]153;154 %mul = mul i32 %area, 12155 %rem = and i32 %mul, 4156 ret i32 %rem157}158 159define <4 x i1> @pr40493_vec1(<4 x i32> %area) {160; CHECK-LABEL: @pr40493_vec1(161; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[AREA:%.*]], splat (i32 1)162; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[TMP1]], zeroinitializer163; CHECK-NEXT: ret <4 x i1> [[CMP]]164;165 %mul = mul <4 x i32> %area, <i32 12, i32 12, i32 12, i32 12>166 %rem = and <4 x i32> %mul, <i32 4, i32 4, i32 4, i32 4>167 %cmp = icmp eq <4 x i32> %rem, zeroinitializer168 ret <4 x i1> %cmp169}170 171define <4 x i1> @pr40493_vec2(<4 x i32> %area) {172; CHECK-LABEL: @pr40493_vec2(173; CHECK-NEXT: [[MUL:%.*]] = mul <4 x i32> [[AREA:%.*]], <i32 12, i32 12, i32 12, i32 undef>174; CHECK-NEXT: [[REM:%.*]] = and <4 x i32> [[MUL]], splat (i32 4)175; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[REM]], zeroinitializer176; CHECK-NEXT: ret <4 x i1> [[CMP]]177;178 %mul = mul <4 x i32> %area, <i32 12, i32 12, i32 12, i32 undef>179 %rem = and <4 x i32> %mul, <i32 4, i32 4, i32 4, i32 4>180 %cmp = icmp eq <4 x i32> %rem, zeroinitializer181 ret <4 x i1> %cmp182}183 184define <4 x i1> @pr40493_vec3(<4 x i32> %area) {185; CHECK-LABEL: @pr40493_vec3(186; CHECK-NEXT: [[MUL:%.*]] = mul <4 x i32> [[AREA:%.*]], splat (i32 12)187; CHECK-NEXT: [[REM:%.*]] = and <4 x i32> [[MUL]], <i32 4, i32 4, i32 4, i32 undef>188; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[REM]], zeroinitializer189; CHECK-NEXT: ret <4 x i1> [[CMP]]190;191 %mul = mul <4 x i32> %area, <i32 12, i32 12, i32 12, i32 12>192 %rem = and <4 x i32> %mul, <i32 4, i32 4, i32 4, i32 undef>193 %cmp = icmp eq <4 x i32> %rem, zeroinitializer194 ret <4 x i1> %cmp195}196 197define <4 x i1> @pr40493_vec4(<4 x i32> %area) {198; CHECK-LABEL: @pr40493_vec4(199; CHECK-NEXT: [[MUL:%.*]] = mul <4 x i32> [[AREA:%.*]], <i32 12, i32 12, i32 12, i32 undef>200; CHECK-NEXT: [[REM:%.*]] = and <4 x i32> [[MUL]], <i32 4, i32 4, i32 4, i32 undef>201; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[REM]], zeroinitializer202; CHECK-NEXT: ret <4 x i1> [[CMP]]203;204 %mul = mul <4 x i32> %area, <i32 12, i32 12, i32 12, i32 undef>205 %rem = and <4 x i32> %mul, <i32 4, i32 4, i32 4, i32 undef>206 %cmp = icmp eq <4 x i32> %rem, zeroinitializer207 ret <4 x i1> %cmp208}209 210define <4 x i1> @pr40493_vec5(<4 x i32> %area) {211; CHECK-LABEL: @pr40493_vec5(212; CHECK-NEXT: [[MUL:%.*]] = mul <4 x i32> [[AREA:%.*]], <i32 12, i32 12, i32 20, i32 20>213; CHECK-NEXT: [[REM:%.*]] = and <4 x i32> [[MUL]], <i32 2, i32 4, i32 2, i32 4>214; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[REM]], zeroinitializer215; CHECK-NEXT: ret <4 x i1> [[CMP]]216;217 %mul = mul <4 x i32> %area, <i32 12, i32 12, i32 20, i32 20>218 %rem = and <4 x i32> %mul, <i32 2, i32 4, i32 2, i32 4>219 %cmp = icmp eq <4 x i32> %rem, zeroinitializer220 ret <4 x i1> %cmp221}222 223define i1 @pr51551(i32 %x, i32 %y) {224; CHECK-LABEL: @pr51551(225; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3226; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0227; CHECK-NEXT: ret i1 [[CMP]]228;229 %t0 = and i32 %y, -7230 %t1 = or i32 %t0, 1231 %mul = mul nsw i32 %t1, %x232 %and = and i32 %mul, 3233 %cmp = icmp eq i32 %and, 0234 ret i1 %cmp235}236 237define i1 @pr51551_2(i32 %x, i32 %y) {238; CHECK-LABEL: @pr51551_2(239; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1240; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0241; CHECK-NEXT: ret i1 [[CMP]]242;243 %t0 = and i32 %y, -7244 %t1 = or i32 %t0, 1245 %mul = mul nsw i32 %t1, %x246 %and = and i32 %mul, 1247 %cmp = icmp eq i32 %and, 0248 ret i1 %cmp249}250 251define i1 @pr51551_neg1(i32 %x, i32 %y) {252; CHECK-LABEL: @pr51551_neg1(253; CHECK-NEXT: [[T0:%.*]] = and i32 [[Y:%.*]], 4254; CHECK-NEXT: [[T1:%.*]] = or disjoint i32 [[T0]], 1255; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[T1]], [[X:%.*]]256; CHECK-NEXT: [[AND:%.*]] = and i32 [[MUL]], 7257; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0258; CHECK-NEXT: ret i1 [[CMP]]259;260 %t0 = and i32 %y, -3261 %t1 = or i32 %t0, 1262 %mul = mul nsw i32 %t1, %x263 %and = and i32 %mul, 7264 %cmp = icmp eq i32 %and, 0265 ret i1 %cmp266}267 268define i1 @pr51551_neg2(i32 %x, i32 %y) {269; CHECK-LABEL: @pr51551_neg2(270; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[Y:%.*]] to i1271; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X:%.*]], 7272; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[TMP2]], 0273; CHECK-NEXT: [[DOTNOT:%.*]] = xor i1 [[TMP1]], true274; CHECK-NEXT: [[CMP:%.*]] = select i1 [[DOTNOT]], i1 true, i1 [[CMP1]]275; CHECK-NEXT: ret i1 [[CMP]]276;277 %t0 = and i32 %y, -7278 %mul = mul nsw i32 %t0, %x279 %and = and i32 %mul, 7280 %cmp = icmp eq i32 %and, 0281 ret i1 %cmp282}283 284define i32 @pr51551_demand3bits(i32 %x, i32 %y) {285; CHECK-LABEL: @pr51551_demand3bits(286; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 7287; CHECK-NEXT: ret i32 [[AND]]288;289 %t0 = and i32 %y, -7290 %t1 = or i32 %t0, 1291 %mul = mul nsw i32 %t1, %x292 %and = and i32 %mul, 7293 ret i32 %and294}295