998 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; General pattern:5; X & Y6;7; Where Y is checking that all the high bits (covered by a mask 4294967168)8; are uniform, i.e. %arg & 4294967168 can be either 4294967168 or 09; Pattern can be one of:10; %t = add i32 %arg, 12811; %r = icmp ult i32 %t, 25612; Or13; %t0 = shl i32 %arg, 2414; %t1 = ashr i32 %t0, 2415; %r = icmp eq i32 %t1, %arg16; Or17; %t0 = trunc i32 %arg to i818; %t1 = sext i8 %t0 to i3219; %r = icmp eq i32 %t1, %arg20; This pattern is a signed truncation check.21;22; And X is checking that some bit in that same mask is zero.23; I.e. can be one of:24; %r = icmp sgt i32 %arg, -125; Or26; %t = and i32 %arg, 214748364827; %r = icmp eq i32 %t, 028;29; Since we are checking that all the bits in that mask are the same,30; and a particular bit is zero, what we are really checking is that all the31; masked bits are zero.32; So this should be transformed to:33; %r = icmp ult i32 %arg, 12834 35; ============================================================================ ;36; Basic positive test37; ============================================================================ ;38 39define i1 @positive_with_signbit(i32 %arg) {40; CHECK-LABEL: @positive_with_signbit(41; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 12842; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]43;44 %t1 = icmp sgt i32 %arg, -145 %t2 = add i32 %arg, 12846 %t3 = icmp ult i32 %t2, 25647 %t4 = and i1 %t1, %t348 ret i1 %t449}50 51define i1 @positive_with_signbit_logical(i32 %arg) {52; CHECK-LABEL: @positive_with_signbit_logical(53; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 12854; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]55;56 %t1 = icmp sgt i32 %arg, -157 %t2 = add i32 %arg, 12858 %t3 = icmp ult i32 %t2, 25659 %t4 = select i1 %t1, i1 %t3, i1 false60 ret i1 %t461}62 63define i1 @positive_with_mask(i32 %arg) {64; CHECK-LABEL: @positive_with_mask(65; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 12866; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]67;68 %t1 = and i32 %arg, 110729625669 %t2 = icmp eq i32 %t1, 070 %t3 = add i32 %arg, 12871 %t4 = icmp ult i32 %t3, 25672 %t5 = and i1 %t2, %t473 ret i1 %t574}75 76define i1 @positive_with_mask_logical(i32 %arg) {77; CHECK-LABEL: @positive_with_mask_logical(78; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 12879; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]80;81 %t1 = and i32 %arg, 110729625682 %t2 = icmp eq i32 %t1, 083 %t3 = add i32 %arg, 12884 %t4 = icmp ult i32 %t3, 25685 %t5 = select i1 %t2, i1 %t4, i1 false86 ret i1 %t587}88 89define i1 @positive_with_icmp(i32 %arg) {90; CHECK-LABEL: @positive_with_icmp(91; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 12892; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]93;94 %t1 = icmp ult i32 %arg, 51295 %t2 = add i32 %arg, 12896 %t3 = icmp ult i32 %t2, 25697 %t4 = and i1 %t1, %t398 ret i1 %t499}100 101define i1 @positive_with_icmp_logical(i32 %arg) {102; CHECK-LABEL: @positive_with_icmp_logical(103; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128104; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]105;106 %t1 = icmp ult i32 %arg, 512107 %t2 = add i32 %arg, 128108 %t3 = icmp ult i32 %t2, 256109 %t4 = select i1 %t1, i1 %t3, i1 false110 ret i1 %t4111}112 113; Still the same114define i1 @positive_with_aggressive_icmp(i32 %arg) {115; CHECK-LABEL: @positive_with_aggressive_icmp(116; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128117; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]118;119 %t1 = icmp ult i32 %arg, 128120 %t2 = add i32 %arg, 256121 %t3 = icmp ult i32 %t2, 512122 %t4 = and i1 %t1, %t3123 ret i1 %t4124}125 126define i1 @positive_with_aggressive_icmp_logical(i32 %arg) {127; CHECK-LABEL: @positive_with_aggressive_icmp_logical(128; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128129; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]130;131 %t1 = icmp ult i32 %arg, 128132 %t2 = add i32 %arg, 256133 %t3 = icmp ult i32 %t2, 512134 %t4 = select i1 %t1, i1 %t3, i1 false135 ret i1 %t4136}137 138; I'm sure there is a bunch more patterns possible :/139 140; This used to trigger an assert, because the icmp's are not direct141; operands of the and.142define i1 @positive_with_extra_and(i32 %arg, i1 %z) {143; CHECK-LABEL: @positive_with_extra_and(144; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128145; CHECK-NEXT: [[T5:%.*]] = and i1 [[T5_SIMPLIFIED]], [[Z:%.*]]146; CHECK-NEXT: ret i1 [[T5]]147;148 %t1 = icmp sgt i32 %arg, -1149 %t2 = add i32 %arg, 128150 %t3 = icmp ult i32 %t2, 256151 %t4 = and i1 %t1, %z152 %t5 = and i1 %t3, %t4153 ret i1 %t5154}155 156define i1 @positive_with_extra_and_logical(i32 %arg, i1 %z) {157; CHECK-LABEL: @positive_with_extra_and_logical(158; CHECK-NEXT: [[DOTSIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128159; CHECK-NEXT: [[T5:%.*]] = select i1 [[DOTSIMPLIFIED]], i1 [[Z:%.*]], i1 false160; CHECK-NEXT: ret i1 [[T5]]161;162 %t1 = icmp sgt i32 %arg, -1163 %t2 = add i32 %arg, 128164 %t3 = icmp ult i32 %t2, 256165 %t4 = select i1 %t1, i1 %z, i1 false166 %t5 = select i1 %t3, i1 %t4, i1 false167 ret i1 %t5168}169 170; ============================================================================ ;171; Vector tests172; ============================================================================ ;173 174define <2 x i1> @positive_vec_splat(<2 x i32> %arg) {175; CHECK-LABEL: @positive_vec_splat(176; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <2 x i32> [[ARG:%.*]], splat (i32 128)177; CHECK-NEXT: ret <2 x i1> [[T4_SIMPLIFIED]]178;179 %t1 = icmp sgt <2 x i32> %arg, <i32 -1, i32 -1>180 %t2 = add <2 x i32> %arg, <i32 128, i32 128>181 %t3 = icmp ult <2 x i32> %t2, <i32 256, i32 256>182 %t4 = and <2 x i1> %t1, %t3183 ret <2 x i1> %t4184}185 186define <2 x i1> @positive_vec_nonsplat(<2 x i32> %arg) {187; CHECK-LABEL: @positive_vec_nonsplat(188; CHECK-NEXT: [[T1:%.*]] = icmp sgt <2 x i32> [[ARG:%.*]], splat (i32 -1)189; CHECK-NEXT: [[T2:%.*]] = add <2 x i32> [[ARG]], <i32 128, i32 256>190; CHECK-NEXT: [[T3:%.*]] = icmp ult <2 x i32> [[T2]], <i32 256, i32 512>191; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T1]], [[T3]]192; CHECK-NEXT: ret <2 x i1> [[T4]]193;194 %t1 = icmp sgt <2 x i32> %arg, <i32 -1, i32 -1>195 %t2 = add <2 x i32> %arg, <i32 128, i32 256>196 %t3 = icmp ult <2 x i32> %t2, <i32 256, i32 512>197 %t4 = and <2 x i1> %t1, %t3198 ret <2 x i1> %t4199}200 201define <3 x i1> @positive_vec_poison0(<3 x i32> %arg) {202; CHECK-LABEL: @positive_vec_poison0(203; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], splat (i32 128)204; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]205;206 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>207 %t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>208 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 256, i32 256>209 %t4 = and <3 x i1> %t1, %t3210 ret <3 x i1> %t4211}212 213define <3 x i1> @positive_vec_poison1(<3 x i32> %arg) {214; CHECK-LABEL: @positive_vec_poison1(215; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], splat (i32 128)216; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]217;218 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>219 %t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>220 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 256, i32 256>221 %t4 = and <3 x i1> %t1, %t3222 ret <3 x i1> %t4223}224 225define <3 x i1> @positive_vec_poison2(<3 x i32> %arg) {226; CHECK-LABEL: @positive_vec_poison2(227; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], splat (i32 128)228; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]229;230 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>231 %t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>232 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 poison, i32 256>233 %t4 = and <3 x i1> %t1, %t3234 ret <3 x i1> %t4235}236 237define <3 x i1> @positive_vec_poison3(<3 x i32> %arg) {238; CHECK-LABEL: @positive_vec_poison3(239; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], splat (i32 128)240; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]241;242 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>243 %t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>244 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 256, i32 256>245 %t4 = and <3 x i1> %t1, %t3246 ret <3 x i1> %t4247}248 249define <3 x i1> @positive_vec_poison4(<3 x i32> %arg) {250; CHECK-LABEL: @positive_vec_poison4(251; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], splat (i32 128)252; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]253;254 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>255 %t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>256 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 poison, i32 256>257 %t4 = and <3 x i1> %t1, %t3258 ret <3 x i1> %t4259}260 261define <3 x i1> @positive_vec_poison5(<3 x i32> %arg) {262; CHECK-LABEL: @positive_vec_poison5(263; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], splat (i32 128)264; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]265;266 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>267 %t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>268 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 poison, i32 256>269 %t4 = and <3 x i1> %t1, %t3270 ret <3 x i1> %t4271}272 273define <3 x i1> @positive_vec_poison6(<3 x i32> %arg) {274; CHECK-LABEL: @positive_vec_poison6(275; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], splat (i32 128)276; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]277;278 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>279 %t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>280 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 poison, i32 256>281 %t4 = and <3 x i1> %t1, %t3282 ret <3 x i1> %t4283}284 285; ============================================================================ ;286; Commutativity tests.287; ============================================================================ ;288 289declare i32 @gen32()290 291define i1 @commutative() {292; CHECK-LABEL: @commutative(293; CHECK-NEXT: [[ARG:%.*]] = call i32 @gen32()294; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128295; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]296;297 %arg = call i32 @gen32()298 %t1 = icmp sgt i32 %arg, -1299 %t2 = add i32 %arg, 128300 %t3 = icmp ult i32 %t2, 256301 %t4 = and i1 %t3, %t1 ; swapped order302 ret i1 %t4303}304 305define i1 @commutative_logical() {306; CHECK-LABEL: @commutative_logical(307; CHECK-NEXT: [[ARG:%.*]] = call i32 @gen32()308; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128309; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]310;311 %arg = call i32 @gen32()312 %t1 = icmp sgt i32 %arg, -1313 %t2 = add i32 %arg, 128314 %t3 = icmp ult i32 %t2, 256315 %t4 = select i1 %t3, i1 %t1, i1 false ; swapped order316 ret i1 %t4317}318 319define i1 @commutative_with_icmp() {320; CHECK-LABEL: @commutative_with_icmp(321; CHECK-NEXT: [[ARG:%.*]] = call i32 @gen32()322; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128323; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]324;325 %arg = call i32 @gen32()326 %t1 = icmp ult i32 %arg, 512327 %t2 = add i32 %arg, 128328 %t3 = icmp ult i32 %t2, 256329 %t4 = and i1 %t3, %t1 ; swapped order330 ret i1 %t4331}332 333define i1 @commutative_with_icmp_logical() {334; CHECK-LABEL: @commutative_with_icmp_logical(335; CHECK-NEXT: [[ARG:%.*]] = call i32 @gen32()336; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128337; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]338;339 %arg = call i32 @gen32()340 %t1 = icmp ult i32 %arg, 512341 %t2 = add i32 %arg, 128342 %t3 = icmp ult i32 %t2, 256343 %t4 = select i1 %t3, i1 %t1, i1 false ; swapped order344 ret i1 %t4345}346 347; ============================================================================ ;348; Truncations.349; ============================================================================ ;350 351define i1 @positive_trunc_signbit(i32 %arg) {352; CHECK-LABEL: @positive_trunc_signbit(353; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128354; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]355;356 %t1 = trunc i32 %arg to i8357 %t2 = icmp sgt i8 %t1, -1358 %t3 = add i32 %arg, 128359 %t4 = icmp ult i32 %t3, 256360 %t5 = and i1 %t2, %t4361 ret i1 %t5362}363 364define i1 @positive_trunc_signbit_logical(i32 %arg) {365; CHECK-LABEL: @positive_trunc_signbit_logical(366; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128367; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]368;369 %t1 = trunc i32 %arg to i8370 %t2 = icmp sgt i8 %t1, -1371 %t3 = add i32 %arg, 128372 %t4 = icmp ult i32 %t3, 256373 %t5 = select i1 %t2, i1 %t4, i1 false374 ret i1 %t5375}376 377define i1 @positive_trunc_base(i32 %arg) {378; CHECK-LABEL: @positive_trunc_base(379; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG:%.*]], 65408380; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp eq i32 [[TMP1]], 0381; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]382;383 %t1 = trunc i32 %arg to i16384 %t2 = icmp sgt i16 %t1, -1385 %t3 = add i16 %t1, 128386 %t4 = icmp ult i16 %t3, 256387 %t5 = and i1 %t2, %t4388 ret i1 %t5389}390 391define i1 @positive_trunc_base_logical(i32 %arg) {392; CHECK-LABEL: @positive_trunc_base_logical(393; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG:%.*]], 65408394; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp eq i32 [[TMP1]], 0395; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]396;397 %t1 = trunc i32 %arg to i16398 %t2 = icmp sgt i16 %t1, -1399 %t3 = add i16 %t1, 128400 %t4 = icmp ult i16 %t3, 256401 %t5 = select i1 %t2, i1 %t4, i1 false402 ret i1 %t5403}404 405define i1 @positive_different_trunc_both(i32 %arg) {406; CHECK-LABEL: @positive_different_trunc_both(407; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG:%.*]], 16384408; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[TMP1]], 0409; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[ARG]] to i16410; CHECK-NEXT: [[T4:%.*]] = add i16 [[T3]], 128411; CHECK-NEXT: [[T5:%.*]] = icmp ult i16 [[T4]], 256412; CHECK-NEXT: [[T6:%.*]] = and i1 [[T2]], [[T5]]413; CHECK-NEXT: ret i1 [[T6]]414;415 %t1 = trunc i32 %arg to i15416 %t2 = icmp sgt i15 %t1, -1417 %t3 = trunc i32 %arg to i16418 %t4 = add i16 %t3, 128419 %t5 = icmp ult i16 %t4, 256420 %t6 = and i1 %t2, %t5421 ret i1 %t6422}423 424define i1 @positive_different_trunc_both_logical(i32 %arg) {425; CHECK-LABEL: @positive_different_trunc_both_logical(426; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG:%.*]], 16384427; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[TMP1]], 0428; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[ARG]] to i16429; CHECK-NEXT: [[T4:%.*]] = add i16 [[T3]], 128430; CHECK-NEXT: [[T5:%.*]] = icmp ult i16 [[T4]], 256431; CHECK-NEXT: [[T6:%.*]] = select i1 [[T2]], i1 [[T5]], i1 false432; CHECK-NEXT: ret i1 [[T6]]433;434 %t1 = trunc i32 %arg to i15435 %t2 = icmp sgt i15 %t1, -1436 %t3 = trunc i32 %arg to i16437 %t4 = add i16 %t3, 128438 %t5 = icmp ult i16 %t4, 256439 %t6 = select i1 %t2, i1 %t5, i1 false440 ret i1 %t6441}442 443; ============================================================================ ;444; One-use tests.445;446; We will only produce one instruction, so we do not care about one-use.447; But, we *could* handle more patterns that we weren't able to canonicalize448; because of extra-uses.449; ============================================================================ ;450 451declare void @use32(i32)452declare void @use8(i8)453declare void @use1(i1)454 455define i1 @oneuse_with_signbit(i32 %arg) {456; CHECK-LABEL: @oneuse_with_signbit(457; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1458; CHECK-NEXT: call void @use1(i1 [[T1]])459; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG]], 128460; CHECK-NEXT: call void @use32(i32 [[T2]])461; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256462; CHECK-NEXT: call void @use1(i1 [[T3]])463; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128464; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]465;466 %t1 = icmp sgt i32 %arg, -1467 call void @use1(i1 %t1)468 %t2 = add i32 %arg, 128469 call void @use32(i32 %t2)470 %t3 = icmp ult i32 %t2, 256471 call void @use1(i1 %t3)472 %t4 = and i1 %t1, %t3473 ret i1 %t4474}475 476define i1 @oneuse_with_signbit_logical(i32 %arg) {477; CHECK-LABEL: @oneuse_with_signbit_logical(478; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1479; CHECK-NEXT: call void @use1(i1 [[T1]])480; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG]], 128481; CHECK-NEXT: call void @use32(i32 [[T2]])482; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256483; CHECK-NEXT: call void @use1(i1 [[T3]])484; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128485; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]486;487 %t1 = icmp sgt i32 %arg, -1488 call void @use1(i1 %t1)489 %t2 = add i32 %arg, 128490 call void @use32(i32 %t2)491 %t3 = icmp ult i32 %t2, 256492 call void @use1(i1 %t3)493 %t4 = select i1 %t1, i1 %t3, i1 false494 ret i1 %t4495}496 497define i1 @oneuse_with_mask(i32 %arg) {498; CHECK-LABEL: @oneuse_with_mask(499; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 603979776500; CHECK-NEXT: call void @use32(i32 [[T1]])501; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0502; CHECK-NEXT: call void @use1(i1 [[T2]])503; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128504; CHECK-NEXT: call void @use32(i32 [[T3]])505; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256506; CHECK-NEXT: call void @use1(i1 [[T4]])507; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128508; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]509;510 %t1 = and i32 %arg, 603979776 ; some bit within the target 4294967168 mask.511 call void @use32(i32 %t1)512 %t2 = icmp eq i32 %t1, 0513 call void @use1(i1 %t2)514 %t3 = add i32 %arg, 128515 call void @use32(i32 %t3)516 %t4 = icmp ult i32 %t3, 256517 call void @use1(i1 %t4)518 %t5 = and i1 %t2, %t4519 ret i1 %t5520}521 522define i1 @oneuse_with_mask_logical(i32 %arg) {523; CHECK-LABEL: @oneuse_with_mask_logical(524; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 603979776525; CHECK-NEXT: call void @use32(i32 [[T1]])526; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0527; CHECK-NEXT: call void @use1(i1 [[T2]])528; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128529; CHECK-NEXT: call void @use32(i32 [[T3]])530; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256531; CHECK-NEXT: call void @use1(i1 [[T4]])532; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128533; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]534;535 %t1 = and i32 %arg, 603979776 ; some bit within the target 4294967168 mask.536 call void @use32(i32 %t1)537 %t2 = icmp eq i32 %t1, 0538 call void @use1(i1 %t2)539 %t3 = add i32 %arg, 128540 call void @use32(i32 %t3)541 %t4 = icmp ult i32 %t3, 256542 call void @use1(i1 %t4)543 %t5 = select i1 %t2, i1 %t4, i1 false544 ret i1 %t5545}546 547define i1 @oneuse_shl_ashr(i32 %arg) {548; CHECK-LABEL: @oneuse_shl_ashr(549; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8550; CHECK-NEXT: call void @use8(i8 [[T1]])551; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[T1]], -1552; CHECK-NEXT: call void @use1(i1 [[T2]])553; CHECK-NEXT: [[T3:%.*]] = shl i32 [[ARG]], 24554; CHECK-NEXT: call void @use32(i32 [[T3]])555; CHECK-NEXT: [[T4:%.*]] = ashr exact i32 [[T3]], 24556; CHECK-NEXT: call void @use32(i32 [[T4]])557; CHECK-NEXT: [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]558; CHECK-NEXT: call void @use1(i1 [[T5]])559; CHECK-NEXT: [[T6:%.*]] = and i1 [[T2]], [[T5]]560; CHECK-NEXT: ret i1 [[T6]]561;562 %t1 = trunc i32 %arg to i8563 call void @use8(i8 %t1)564 %t2 = icmp sgt i8 %t1, -1565 call void @use1(i1 %t2)566 %t3 = shl i32 %arg, 24567 call void @use32(i32 %t3)568 %t4 = ashr i32 %t3, 24569 call void @use32(i32 %t4)570 %t5 = icmp eq i32 %t4, %arg571 call void @use1(i1 %t5)572 %t6 = and i1 %t2, %t5573 ret i1 %t6574}575 576define i1 @oneuse_shl_ashr_logical(i32 %arg) {577; CHECK-LABEL: @oneuse_shl_ashr_logical(578; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8579; CHECK-NEXT: call void @use8(i8 [[T1]])580; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[T1]], -1581; CHECK-NEXT: call void @use1(i1 [[T2]])582; CHECK-NEXT: [[T3:%.*]] = shl i32 [[ARG]], 24583; CHECK-NEXT: call void @use32(i32 [[T3]])584; CHECK-NEXT: [[T4:%.*]] = ashr exact i32 [[T3]], 24585; CHECK-NEXT: call void @use32(i32 [[T4]])586; CHECK-NEXT: [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]587; CHECK-NEXT: call void @use1(i1 [[T5]])588; CHECK-NEXT: [[T6:%.*]] = select i1 [[T2]], i1 [[T5]], i1 false589; CHECK-NEXT: ret i1 [[T6]]590;591 %t1 = trunc i32 %arg to i8592 call void @use8(i8 %t1)593 %t2 = icmp sgt i8 %t1, -1594 call void @use1(i1 %t2)595 %t3 = shl i32 %arg, 24596 call void @use32(i32 %t3)597 %t4 = ashr i32 %t3, 24598 call void @use32(i32 %t4)599 %t5 = icmp eq i32 %t4, %arg600 call void @use1(i1 %t5)601 %t6 = select i1 %t2, i1 %t5, i1 false602 ret i1 %t6603}604 605define zeroext i1 @oneuse_trunc_sext(i32 %arg) {606; CHECK-LABEL: @oneuse_trunc_sext(607; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8608; CHECK-NEXT: call void @use8(i8 [[T1]])609; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[T1]], -1610; CHECK-NEXT: call void @use1(i1 [[T2]])611; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[ARG]] to i8612; CHECK-NEXT: call void @use8(i8 [[T3]])613; CHECK-NEXT: [[T4:%.*]] = sext i8 [[T3]] to i32614; CHECK-NEXT: call void @use32(i32 [[T4]])615; CHECK-NEXT: [[T5:%.*]] = icmp eq i32 [[ARG]], [[T4]]616; CHECK-NEXT: call void @use1(i1 [[T5]])617; CHECK-NEXT: [[T6:%.*]] = and i1 [[T2]], [[T5]]618; CHECK-NEXT: ret i1 [[T6]]619;620 %t1 = trunc i32 %arg to i8621 call void @use8(i8 %t1)622 %t2 = icmp sgt i8 %t1, -1623 call void @use1(i1 %t2)624 %t3 = trunc i32 %arg to i8625 call void @use8(i8 %t3)626 %t4 = sext i8 %t3 to i32627 call void @use32(i32 %t4)628 %t5 = icmp eq i32 %t4, %arg629 call void @use1(i1 %t5)630 %t6 = and i1 %t2, %t5631 ret i1 %t6632}633 634define zeroext i1 @oneuse_trunc_sext_logical(i32 %arg) {635; CHECK-LABEL: @oneuse_trunc_sext_logical(636; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8637; CHECK-NEXT: call void @use8(i8 [[T1]])638; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[T1]], -1639; CHECK-NEXT: call void @use1(i1 [[T2]])640; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[ARG]] to i8641; CHECK-NEXT: call void @use8(i8 [[T3]])642; CHECK-NEXT: [[T4:%.*]] = sext i8 [[T3]] to i32643; CHECK-NEXT: call void @use32(i32 [[T4]])644; CHECK-NEXT: [[T5:%.*]] = icmp eq i32 [[ARG]], [[T4]]645; CHECK-NEXT: call void @use1(i1 [[T5]])646; CHECK-NEXT: [[T6:%.*]] = select i1 [[T2]], i1 [[T5]], i1 false647; CHECK-NEXT: ret i1 [[T6]]648;649 %t1 = trunc i32 %arg to i8650 call void @use8(i8 %t1)651 %t2 = icmp sgt i8 %t1, -1652 call void @use1(i1 %t2)653 %t3 = trunc i32 %arg to i8654 call void @use8(i8 %t3)655 %t4 = sext i8 %t3 to i32656 call void @use32(i32 %t4)657 %t5 = icmp eq i32 %t4, %arg658 call void @use1(i1 %t5)659 %t6 = select i1 %t2, i1 %t5, i1 false660 ret i1 %t6661}662 663; ============================================================================ ;664; Negative tests665; ============================================================================ ;666 667define i1 @negative_not_arg(i32 %arg, i32 %arg2) {668; CHECK-LABEL: @negative_not_arg(669; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1670; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG2:%.*]], 128671; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256672; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]673; CHECK-NEXT: ret i1 [[T4]]674;675 %t1 = icmp sgt i32 %arg, -1676 %t2 = add i32 %arg2, 128 ; not %arg677 %t3 = icmp ult i32 %t2, 256678 %t4 = and i1 %t1, %t3679 ret i1 %t4680}681 682define i1 @negative_not_arg_logical(i32 %arg, i32 %arg2) {683; CHECK-LABEL: @negative_not_arg_logical(684; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1685; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG2:%.*]], 128686; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256687; CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i1 [[T3]], i1 false688; CHECK-NEXT: ret i1 [[T4]]689;690 %t1 = icmp sgt i32 %arg, -1691 %t2 = add i32 %arg2, 128 ; not %arg692 %t3 = icmp ult i32 %t2, 256693 %t4 = select i1 %t1, i1 %t3, i1 false694 ret i1 %t4695}696 697define i1 @negative_trunc_not_arg(i32 %arg, i32 %arg2) {698; CHECK-LABEL: @negative_trunc_not_arg(699; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG:%.*]], 128700; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[TMP1]], 0701; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG2:%.*]], 128702; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256703; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]704; CHECK-NEXT: ret i1 [[T5]]705;706 %t1 = trunc i32 %arg to i8707 %t2 = icmp sgt i8 %t1, -1708 %t3 = add i32 %arg2, 128 ; not %arg709 %t4 = icmp ult i32 %t3, 256710 %t5 = and i1 %t2, %t4711 ret i1 %t5712}713 714define i1 @negative_trunc_not_arg_logical(i32 %arg, i32 %arg2) {715; CHECK-LABEL: @negative_trunc_not_arg_logical(716; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG:%.*]], 128717; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[TMP1]], 0718; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG2:%.*]], 128719; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256720; CHECK-NEXT: [[T5:%.*]] = select i1 [[T2]], i1 [[T4]], i1 false721; CHECK-NEXT: ret i1 [[T5]]722;723 %t1 = trunc i32 %arg to i8724 %t2 = icmp sgt i8 %t1, -1725 %t3 = add i32 %arg2, 128 ; not %arg726 %t4 = icmp ult i32 %t3, 256727 %t5 = select i1 %t2, i1 %t4, i1 false728 ret i1 %t5729}730 731define i1 @positive_with_mask_not_arg(i32 %arg, i32 %arg2) {732; CHECK-LABEL: @positive_with_mask_not_arg(733; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1140850688734; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0735; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG2:%.*]], 128736; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256737; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]738; CHECK-NEXT: ret i1 [[T5]]739;740 %t1 = and i32 %arg, 1140850688741 %t2 = icmp eq i32 %t1, 0742 %t3 = add i32 %arg2, 128 ; not %arg743 %t4 = icmp ult i32 %t3, 256744 %t5 = and i1 %t2, %t4745 ret i1 %t5746}747 748define i1 @positive_with_mask_not_arg_logical(i32 %arg, i32 %arg2) {749; CHECK-LABEL: @positive_with_mask_not_arg_logical(750; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1140850688751; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0752; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG2:%.*]], 128753; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256754; CHECK-NEXT: [[T5:%.*]] = select i1 [[T2]], i1 [[T4]], i1 false755; CHECK-NEXT: ret i1 [[T5]]756;757 %t1 = and i32 %arg, 1140850688758 %t2 = icmp eq i32 %t1, 0759 %t3 = add i32 %arg2, 128 ; not %arg760 %t4 = icmp ult i32 %t3, 256761 %t5 = select i1 %t2, i1 %t4, i1 false762 ret i1 %t5763}764 765define i1 @negative_with_nonuniform_bad_mask(i32 %arg) {766; CHECK-LABEL: @negative_with_nonuniform_bad_mask(767; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1711276033768; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0769; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128770; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256771; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]772; CHECK-NEXT: ret i1 [[T5]]773;774 %t1 = and i32 %arg, 1711276033 ; lowest bit is set775 %t2 = icmp eq i32 %t1, 0776 %t3 = add i32 %arg, 128777 %t4 = icmp ult i32 %t3, 256778 %t5 = and i1 %t2, %t4779 ret i1 %t5780}781 782define i1 @negative_with_nonuniform_bad_mask_logical(i32 %arg) {783; CHECK-LABEL: @negative_with_nonuniform_bad_mask_logical(784; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1711276033785; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0786; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128787; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256788; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]789; CHECK-NEXT: ret i1 [[T5]]790;791 %t1 = and i32 %arg, 1711276033 ; lowest bit is set792 %t2 = icmp eq i32 %t1, 0793 %t3 = add i32 %arg, 128794 %t4 = icmp ult i32 %t3, 256795 %t5 = select i1 %t2, i1 %t4, i1 false796 ret i1 %t5797}798 799define i1 @negative_with_uniform_bad_mask(i32 %arg) {800; CHECK-LABEL: @negative_with_uniform_bad_mask(801; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], -16777152802; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0803; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128804; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256805; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]806; CHECK-NEXT: ret i1 [[T5]]807;808 %t1 = and i32 %arg, 4278190144 ; 7'th bit is set809 %t2 = icmp eq i32 %t1, 0810 %t3 = add i32 %arg, 128811 %t4 = icmp ult i32 %t3, 256812 %t5 = and i1 %t2, %t4813 ret i1 %t5814}815 816define i1 @negative_with_uniform_bad_mask_logical(i32 %arg) {817; CHECK-LABEL: @negative_with_uniform_bad_mask_logical(818; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], -16777152819; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0820; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128821; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256822; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]823; CHECK-NEXT: ret i1 [[T5]]824;825 %t1 = and i32 %arg, 4278190144 ; 7'th bit is set826 %t2 = icmp eq i32 %t1, 0827 %t3 = add i32 %arg, 128828 %t4 = icmp ult i32 %t3, 256829 %t5 = select i1 %t2, i1 %t4, i1 false830 ret i1 %t5831}832 833define i1 @negative_with_wrong_mask(i32 %arg) {834; CHECK-LABEL: @negative_with_wrong_mask(835; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1836; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0837; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128838; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256839; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]840; CHECK-NEXT: ret i1 [[T5]]841;842 %t1 = and i32 %arg, 1 ; not even checking the right mask843 %t2 = icmp eq i32 %t1, 0844 %t3 = add i32 %arg, 128845 %t4 = icmp ult i32 %t3, 256846 %t5 = and i1 %t2, %t4847 ret i1 %t5848}849 850define i1 @negative_with_wrong_mask_logical(i32 %arg) {851; CHECK-LABEL: @negative_with_wrong_mask_logical(852; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1853; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0854; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128855; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256856; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]857; CHECK-NEXT: ret i1 [[T5]]858;859 %t1 = and i32 %arg, 1 ; not even checking the right mask860 %t2 = icmp eq i32 %t1, 0861 %t3 = add i32 %arg, 128862 %t4 = icmp ult i32 %t3, 256863 %t5 = select i1 %t2, i1 %t4, i1 false864 ret i1 %t5865}866 867define i1 @negative_not_less_than(i32 %arg) {868; CHECK-LABEL: @negative_not_less_than(869; CHECK-NEXT: ret i1 false870;871 %t1 = icmp sgt i32 %arg, -1872 %t2 = add i32 %arg, 256 ; should be less than 256873 %t3 = icmp ult i32 %t2, 256874 %t4 = and i1 %t1, %t3875 ret i1 %t4876}877 878define i1 @negative_not_less_than_logical(i32 %arg) {879; CHECK-LABEL: @negative_not_less_than_logical(880; CHECK-NEXT: ret i1 false881;882 %t1 = icmp sgt i32 %arg, -1883 %t2 = add i32 %arg, 256 ; should be less than 256884 %t3 = icmp ult i32 %t2, 256885 %t4 = select i1 %t1, i1 %t3, i1 false886 ret i1 %t4887}888 889define i1 @negative_not_power_of_two(i32 %arg) {890; CHECK-LABEL: @negative_not_power_of_two(891; CHECK-NEXT: [[T4:%.*]] = icmp eq i32 [[ARG:%.*]], 0892; CHECK-NEXT: ret i1 [[T4]]893;894 %t1 = icmp sgt i32 %arg, -1895 %t2 = add i32 %arg, 255 ; should be power of two896 %t3 = icmp ult i32 %t2, 256897 %t4 = and i1 %t1, %t3898 ret i1 %t4899}900 901define i1 @negative_not_power_of_two_logical(i32 %arg) {902; CHECK-LABEL: @negative_not_power_of_two_logical(903; CHECK-NEXT: [[T4:%.*]] = icmp eq i32 [[ARG:%.*]], 0904; CHECK-NEXT: ret i1 [[T4]]905;906 %t1 = icmp sgt i32 %arg, -1907 %t2 = add i32 %arg, 255 ; should be power of two908 %t3 = icmp ult i32 %t2, 256909 %t4 = select i1 %t1, i1 %t3, i1 false910 ret i1 %t4911}912 913define i1 @negative_not_next_power_of_two(i32 %arg) {914; CHECK-LABEL: @negative_not_next_power_of_two(915; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[ARG:%.*]], 192916; CHECK-NEXT: ret i1 [[T4]]917;918 %t1 = icmp sgt i32 %arg, -1919 %t2 = add i32 %arg, 64 ; should be 256 >> 1920 %t3 = icmp ult i32 %t2, 256921 %t4 = and i1 %t1, %t3922 ret i1 %t4923}924 925define i1 @negative_not_next_power_of_two_logical(i32 %arg) {926; CHECK-LABEL: @negative_not_next_power_of_two_logical(927; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[ARG:%.*]], 192928; CHECK-NEXT: ret i1 [[T4]]929;930 %t1 = icmp sgt i32 %arg, -1931 %t2 = add i32 %arg, 64 ; should be 256 >> 1932 %t3 = icmp ult i32 %t2, 256933 %t4 = select i1 %t1, i1 %t3, i1 false934 ret i1 %t4935}936 937define i1 @two_signed_truncation_checks(i32 %arg) {938; CHECK-LABEL: @two_signed_truncation_checks(939; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[ARG:%.*]], 128940; CHECK-NEXT: [[T5:%.*]] = icmp ult i32 [[TMP1]], 256941; CHECK-NEXT: ret i1 [[T5]]942;943 %t1 = add i32 %arg, 512944 %t2 = icmp ult i32 %t1, 1024945 %t3 = add i32 %arg, 128946 %t4 = icmp ult i32 %t3, 256947 %t5 = and i1 %t2, %t4948 ret i1 %t5949}950 951define i1 @two_signed_truncation_checks_logical(i32 %arg) {952; CHECK-LABEL: @two_signed_truncation_checks_logical(953; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[ARG:%.*]], 128954; CHECK-NEXT: [[T5:%.*]] = icmp ult i32 [[TMP1]], 256955; CHECK-NEXT: ret i1 [[T5]]956;957 %t1 = add i32 %arg, 512958 %t2 = icmp ult i32 %t1, 1024959 %t3 = add i32 %arg, 128960 %t4 = icmp ult i32 %t3, 256961 %t5 = select i1 %t2, i1 %t4, i1 false962 ret i1 %t5963}964 965define i1 @bad_trunc_stc(i32 %arg) {966; CHECK-LABEL: @bad_trunc_stc(967; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1968; CHECK-NEXT: [[T2:%.*]] = trunc i32 [[ARG]] to i16969; CHECK-NEXT: [[T3:%.*]] = add i16 [[T2]], 128970; CHECK-NEXT: [[T4:%.*]] = icmp ult i16 [[T3]], 256971; CHECK-NEXT: [[T5:%.*]] = and i1 [[T1]], [[T4]]972; CHECK-NEXT: ret i1 [[T5]]973;974 %t1 = icmp sgt i32 %arg, -1 ; checks a bit outside of the i16975 %t2 = trunc i32 %arg to i16976 %t3 = add i16 %t2, 128977 %t4 = icmp ult i16 %t3, 256978 %t5 = and i1 %t1, %t4979 ret i1 %t5980}981 982define i1 @bad_trunc_stc_logical(i32 %arg) {983; CHECK-LABEL: @bad_trunc_stc_logical(984; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1985; CHECK-NEXT: [[T2:%.*]] = trunc i32 [[ARG]] to i16986; CHECK-NEXT: [[T3:%.*]] = add i16 [[T2]], 128987; CHECK-NEXT: [[T4:%.*]] = icmp ult i16 [[T3]], 256988; CHECK-NEXT: [[T5:%.*]] = select i1 [[T1]], i1 [[T4]], i1 false989; CHECK-NEXT: ret i1 [[T5]]990;991 %t1 = icmp sgt i32 %arg, -1 ; checks a bit outside of the i16992 %t2 = trunc i32 %arg to i16993 %t3 = add i16 %t2, 128994 %t4 = icmp ult i16 %t3, 256995 %t5 = select i1 %t1, i1 %t4, i1 false996 ret i1 %t5997}998