251 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; https://bugs.llvm.org/show_bug.cgi?id=387085 6; Pattern:7; ~(-1 << bits) u< val8; Should be transformed into:9; (val l>> bits) != 010 11; ============================================================================ ;12; Basic positive tests13; ============================================================================ ;14 15define i1 @p0(i8 %val, i8 %bits) {16; CHECK-LABEL: @p0(17; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL:%.*]], [[BITS:%.*]]18; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[VAL_HIGHBITS]], 019; CHECK-NEXT: ret i1 [[R]]20;21 %t0 = shl i8 -1, %bits22 %t1 = xor i8 %t0, -123 %r = icmp ult i8 %t1, %val24 ret i1 %r25}26 27; ============================================================================ ;28; Vector tests29; ============================================================================ ;30 31define <2 x i1> @p1_vec(<2 x i8> %val, <2 x i8> %bits) {32; CHECK-LABEL: @p1_vec(33; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <2 x i8> [[VAL:%.*]], [[BITS:%.*]]34; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[VAL_HIGHBITS]], zeroinitializer35; CHECK-NEXT: ret <2 x i1> [[R]]36;37 %t0 = shl <2 x i8> <i8 -1, i8 -1>, %bits38 %t1 = xor <2 x i8> %t0, <i8 -1, i8 -1>39 %r = icmp ult <2 x i8> %t1, %val40 ret <2 x i1> %r41}42 43define <3 x i1> @p2_vec_poison0(<3 x i8> %val, <3 x i8> %bits) {44; CHECK-LABEL: @p2_vec_poison0(45; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS:%.*]]46; CHECK-NEXT: [[R:%.*]] = icmp ne <3 x i8> [[VAL_HIGHBITS]], zeroinitializer47; CHECK-NEXT: ret <3 x i1> [[R]]48;49 %t0 = shl <3 x i8> <i8 -1, i8 poison, i8 -1>, %bits50 %t1 = xor <3 x i8> %t0, <i8 -1, i8 -1, i8 -1>51 %r = icmp ult <3 x i8> %t1, %val52 ret <3 x i1> %r53}54 55define <3 x i1> @p2_vec_poison1(<3 x i8> %val, <3 x i8> %bits) {56; CHECK-LABEL: @p2_vec_poison1(57; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS:%.*]]58; CHECK-NEXT: [[R:%.*]] = icmp ne <3 x i8> [[VAL_HIGHBITS]], zeroinitializer59; CHECK-NEXT: ret <3 x i1> [[R]]60;61 %t0 = shl <3 x i8> <i8 -1, i8 -1, i8 -1>, %bits62 %t1 = xor <3 x i8> %t0, <i8 -1, i8 poison, i8 -1>63 %r = icmp ult <3 x i8> %t1, %val64 ret <3 x i1> %r65}66 67define <3 x i1> @p2_vec_poison2(<3 x i8> %val, <3 x i8> %bits) {68; CHECK-LABEL: @p2_vec_poison2(69; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS:%.*]]70; CHECK-NEXT: [[R:%.*]] = icmp ne <3 x i8> [[VAL_HIGHBITS]], zeroinitializer71; CHECK-NEXT: ret <3 x i1> [[R]]72;73 %t0 = shl <3 x i8> <i8 -1, i8 poison, i8 -1>, %bits74 %t1 = xor <3 x i8> %t0, <i8 -1, i8 poison, i8 -1>75 %r = icmp ult <3 x i8> %t1, %val76 ret <3 x i1> %r77}78 79; ============================================================================ ;80; Commutativity tests.81; ============================================================================ ;82 83declare i8 @gen8()84 85define i1 @c0(i8 %bits) {86; CHECK-LABEL: @c0(87; CHECK-NEXT: [[VAL:%.*]] = call i8 @gen8()88; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL]], [[BITS:%.*]]89; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[VAL_HIGHBITS]], 090; CHECK-NEXT: ret i1 [[R]]91;92 %t0 = shl i8 -1, %bits93 %t1 = xor i8 %t0, -194 %val = call i8 @gen8()95 %r = icmp ugt i8 %val, %t1 ; swapped order and predicate96 ret i1 %r97}98 99; What if we have the same pattern on both sides?100define i1 @both(i8 %bits0, i8 %bits1) {101; CHECK-LABEL: @both(102; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[BITS0:%.*]]103; CHECK-NEXT: [[T2:%.*]] = shl nsw i8 -1, [[BITS1:%.*]]104; CHECK-NEXT: [[R:%.*]] = icmp samesign ugt i8 [[T0]], [[T2]]105; CHECK-NEXT: ret i1 [[R]]106;107 %t0 = shl i8 -1, %bits0108 %t1 = xor i8 %t0, -1109 %t2 = shl i8 -1, %bits1110 %t3 = xor i8 %t2, -1111 %r = icmp ult i8 %t1, %t3112 ret i1 %r113}114 115; ============================================================================ ;116; One-use tests.117; ============================================================================ ;118 119declare void @use8(i8)120 121define i1 @oneuse0(i8 %val, i8 %bits) {122; CHECK-LABEL: @oneuse0(123; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]124; CHECK-NEXT: call void @use8(i8 [[T0]])125; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL:%.*]], [[BITS]]126; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[VAL_HIGHBITS]], 0127; CHECK-NEXT: ret i1 [[R]]128;129 %t0 = shl i8 -1, %bits130 call void @use8(i8 %t0)131 %t1 = xor i8 %t0, -1132 %r = icmp ult i8 %t1, %val133 ret i1 %r134}135 136define i1 @oneuse1(i8 %val, i8 %bits) {137; CHECK-LABEL: @oneuse1(138; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]139; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1140; CHECK-NEXT: call void @use8(i8 [[T1]])141; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[VAL:%.*]], [[T1]]142; CHECK-NEXT: ret i1 [[R]]143;144 %t0 = shl i8 -1, %bits145 %t1 = xor i8 %t0, -1146 call void @use8(i8 %t1)147 %r = icmp ult i8 %t1, %val148 ret i1 %r149}150 151define i1 @oneuse2(i8 %val, i8 %bits) {152; CHECK-LABEL: @oneuse2(153; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]154; CHECK-NEXT: call void @use8(i8 [[T0]])155; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1156; CHECK-NEXT: call void @use8(i8 [[T1]])157; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[VAL:%.*]], [[T1]]158; CHECK-NEXT: ret i1 [[R]]159;160 %t0 = shl i8 -1, %bits161 call void @use8(i8 %t0)162 %t1 = xor i8 %t0, -1163 call void @use8(i8 %t1)164 %r = icmp ult i8 %t1, %val165 ret i1 %r166}167 168; ============================================================================ ;169; Negative tests170; ============================================================================ ;171 172define i1 @n0(i8 %val, i8 %bits) {173; CHECK-LABEL: @n0(174; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]175; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1176; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[VAL:%.*]], [[T1]]177; CHECK-NEXT: ret i1 [[R]]178;179 %t0 = shl i8 1, %bits ; constant is not -1180 %t1 = xor i8 %t0, -1181 %r = icmp ult i8 %t1, %val182 ret i1 %r183}184 185define i1 @n1(i8 %val, i8 %bits) {186; CHECK-LABEL: @n1(187; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]188; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], 1189; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[T1]], [[VAL:%.*]]190; CHECK-NEXT: ret i1 [[R]]191;192 %t0 = shl i8 -1, %bits193 %t1 = xor i8 %t0, 1 ; not 'not'194 %r = icmp ult i8 %t1, %val195 ret i1 %r196}197 198define <2 x i1> @n2_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {199; CHECK-LABEL: @n2_vec_nonsplat(200; CHECK-NEXT: [[T0:%.*]] = shl <2 x i8> <i8 -1, i8 1>, [[BITS:%.*]]201; CHECK-NEXT: [[T1:%.*]] = xor <2 x i8> [[T0]], splat (i8 -1)202; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[VAL:%.*]], [[T1]]203; CHECK-NEXT: ret <2 x i1> [[R]]204;205 %t0 = shl <2 x i8> <i8 -1, i8 1>, %bits ; again, wrong constant206 %t1 = xor <2 x i8> %t0, <i8 -1, i8 -1>207 %r = icmp ult <2 x i8> %t1, %val208 ret <2 x i1> %r209}210 211define <2 x i1> @n3_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {212; CHECK-LABEL: @n3_vec_nonsplat(213; CHECK-NEXT: [[T0:%.*]] = shl nsw <2 x i8> splat (i8 -1), [[BITS:%.*]]214; CHECK-NEXT: [[T1:%.*]] = xor <2 x i8> [[T0]], <i8 -1, i8 1>215; CHECK-NEXT: [[R:%.*]] = icmp ult <2 x i8> [[T1]], [[VAL:%.*]]216; CHECK-NEXT: ret <2 x i1> [[R]]217;218 %t0 = shl <2 x i8> <i8 -1, i8 -1>, %bits219 %t1 = xor <2 x i8> %t0, <i8 -1, i8 1> ; again, wrong constant220 %r = icmp ult <2 x i8> %t1, %val221 ret <2 x i1> %r222}223 224define i1 @n3(i8 %val, i8 %bits) {225; CHECK-LABEL: @n3(226; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]227; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1228; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[VAL:%.*]], [[T1]]229; CHECK-NEXT: ret i1 [[R]]230;231 %t0 = shl i8 -1, %bits232 %t1 = xor i8 %t0, -1233 %r = icmp ule i8 %t1, %val ; wrong predicate234 ret i1 %r235}236 237define i1 @n4(i8 %bits) {238; CHECK-LABEL: @n4(239; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]240; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1241; CHECK-NEXT: [[VAL:%.*]] = call i8 @gen8()242; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[VAL]], [[T1]]243; CHECK-NEXT: ret i1 [[R]]244;245 %t0 = shl i8 -1, %bits246 %t1 = xor i8 %t0, -1247 %val = call i8 @gen8()248 %r = icmp uge i8 %val, %t1 ; swapped order and [wrong] predicate249 ret i1 %r250}251