243 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; For pattern (X & (signbit l>> Y)) ==/!= 05; it may be optimal to fold into (X << Y) >=/< 06 7; Scalar tests8 9define i1 @scalar_i8_signbit_lshr_and_eq(i8 %x, i8 %y) {10; CHECK-LABEL: @scalar_i8_signbit_lshr_and_eq(11; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i8 -128, [[Y:%.*]]12; CHECK-NEXT: [[AND:%.*]] = and i8 [[LSHR]], [[X:%.*]]13; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 014; CHECK-NEXT: ret i1 [[R]]15;16 %lshr = lshr i8 128, %y17 %and = and i8 %lshr, %x18 %r = icmp eq i8 %and, 019 ret i1 %r20}21 22define i1 @scalar_i16_signbit_lshr_and_eq(i16 %x, i16 %y) {23; CHECK-LABEL: @scalar_i16_signbit_lshr_and_eq(24; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i16 -32768, [[Y:%.*]]25; CHECK-NEXT: [[AND:%.*]] = and i16 [[LSHR]], [[X:%.*]]26; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[AND]], 027; CHECK-NEXT: ret i1 [[R]]28;29 %lshr = lshr i16 32768, %y30 %and = and i16 %lshr, %x31 %r = icmp eq i16 %and, 032 ret i1 %r33}34 35define i1 @scalar_i32_signbit_lshr_and_eq(i32 %x, i32 %y) {36; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq(37; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]38; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]39; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 040; CHECK-NEXT: ret i1 [[R]]41;42 %lshr = lshr i32 2147483648, %y43 %and = and i32 %lshr, %x44 %r = icmp eq i32 %and, 045 ret i1 %r46}47 48define i1 @scalar_i64_signbit_lshr_and_eq(i64 %x, i64 %y) {49; CHECK-LABEL: @scalar_i64_signbit_lshr_and_eq(50; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i64 -9223372036854775808, [[Y:%.*]]51; CHECK-NEXT: [[AND:%.*]] = and i64 [[LSHR]], [[X:%.*]]52; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[AND]], 053; CHECK-NEXT: ret i1 [[R]]54;55 %lshr = lshr i64 9223372036854775808, %y56 %and = and i64 %lshr, %x57 %r = icmp eq i64 %and, 058 ret i1 %r59}60 61define i1 @scalar_i32_signbit_lshr_and_ne(i32 %x, i32 %y) {62; CHECK-LABEL: @scalar_i32_signbit_lshr_and_ne(63; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]64; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]65; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[AND]], 066; CHECK-NEXT: ret i1 [[R]]67;68 %lshr = lshr i32 2147483648, %y69 %and = and i32 %lshr, %x70 %r = icmp ne i32 %and, 0 ; check 'ne' predicate71 ret i1 %r72}73 74; Vector tests75 76define <4 x i1> @vec_4xi32_signbit_lshr_and_eq(<4 x i32> %x, <4 x i32> %y) {77; CHECK-LABEL: @vec_4xi32_signbit_lshr_and_eq(78; CHECK-NEXT: [[LSHR:%.*]] = lshr exact <4 x i32> splat (i32 -2147483648), [[Y:%.*]]79; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], [[X:%.*]]80; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], zeroinitializer81; CHECK-NEXT: ret <4 x i1> [[R]]82;83 %lshr = lshr <4 x i32> <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648>, %y84 %and = and <4 x i32> %lshr, %x85 %r = icmp eq <4 x i32> %and, <i32 0, i32 0, i32 0, i32 0>86 ret <4 x i1> %r87}88 89define <4 x i1> @vec_4xi32_signbit_lshr_and_eq_undef1(<4 x i32> %x, <4 x i32> %y) {90; CHECK-LABEL: @vec_4xi32_signbit_lshr_and_eq_undef1(91; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> <i32 -2147483648, i32 undef, i32 -2147483648, i32 2147473648>, [[Y:%.*]]92; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], [[X:%.*]]93; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], zeroinitializer94; CHECK-NEXT: ret <4 x i1> [[R]]95;96 %lshr = lshr <4 x i32> <i32 2147483648, i32 undef, i32 2147483648, i32 2147473648>, %y97 %and = and <4 x i32> %lshr, %x98 %r = icmp eq <4 x i32> %and, <i32 0, i32 0, i32 0, i32 0>99 ret <4 x i1> %r100}101 102define <4 x i1> @vec_4xi32_signbit_lshr_and_eq_undef2(<4 x i32> %x, <4 x i32> %y) {103; CHECK-LABEL: @vec_4xi32_signbit_lshr_and_eq_undef2(104; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 2147473648>, [[Y:%.*]]105; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], [[X:%.*]]106; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 0, i32 0, i32 0, i32 undef>107; CHECK-NEXT: ret <4 x i1> [[R]]108;109 %lshr = lshr <4 x i32> <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147473648>, %y110 %and = and <4 x i32> %lshr, %x111 %r = icmp eq <4 x i32> %and, <i32 0, i32 0, i32 0, i32 undef>112 ret <4 x i1> %r113}114 115define <4 x i1> @vec_4xi32_signbit_lshr_and_eq_undef3(<4 x i32> %x, <4 x i32> %y) {116; CHECK-LABEL: @vec_4xi32_signbit_lshr_and_eq_undef3(117; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> <i32 -2147483648, i32 undef, i32 -2147483648, i32 2147473648>, [[Y:%.*]]118; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], [[X:%.*]]119; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 undef, i32 0, i32 0, i32 0>120; CHECK-NEXT: ret <4 x i1> [[R]]121;122 %lshr = lshr <4 x i32> <i32 2147483648, i32 undef, i32 2147483648, i32 2147473648>, %y123 %and = and <4 x i32> %lshr, %x124 %r = icmp eq <4 x i32> %and, <i32 undef, i32 0, i32 0, i32 0>125 ret <4 x i1> %r126}127 128; Extra use129 130; Fold happened131define i1 @scalar_i32_signbit_lshr_and_eq_extra_use_lshr(i32 %x, i32 %y, i32 %z, ptr %p) {132; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq_extra_use_lshr(133; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]134; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[LSHR]], [[Z:%.*]]135; CHECK-NEXT: store i32 [[XOR]], ptr [[P:%.*]], align 4136; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]137; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0138; CHECK-NEXT: ret i1 [[R]]139;140 %lshr = lshr i32 2147483648, %y141 %xor = xor i32 %lshr, %z ; extra use of lshr142 store i32 %xor, ptr %p143 %and = and i32 %lshr, %x144 %r = icmp eq i32 %and, 0145 ret i1 %r146}147 148; Not fold149define i1 @scalar_i32_signbit_lshr_and_eq_extra_use_and(i32 %x, i32 %y, i32 %z, ptr %p) {150; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq_extra_use_and(151; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]152; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]153; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[AND]], [[Z:%.*]]154; CHECK-NEXT: store i32 [[MUL]], ptr [[P:%.*]], align 4155; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0156; CHECK-NEXT: ret i1 [[R]]157;158 %lshr = lshr i32 2147483648, %y159 %and = and i32 %lshr, %x160 %mul = mul i32 %and, %z ; extra use of and161 store i32 %mul, ptr %p162 %r = icmp eq i32 %and, 0163 ret i1 %r164}165 166; Not fold167define i1 @scalar_i32_signbit_lshr_and_eq_extra_use_lshr_and(i32 %x, i32 %y, i32 %z, ptr %p, ptr %q) {168; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq_extra_use_lshr_and(169; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]170; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]171; CHECK-NEXT: store i32 [[AND]], ptr [[P:%.*]], align 4172; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LSHR]], [[Z:%.*]]173; CHECK-NEXT: store i32 [[ADD]], ptr [[Q:%.*]], align 4174; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0175; CHECK-NEXT: ret i1 [[R]]176;177 %lshr = lshr i32 2147483648, %y178 %and = and i32 %lshr, %x179 store i32 %and, ptr %p ; extra use of and180 %add = add i32 %lshr, %z ; extra use of lshr181 store i32 %add, ptr %q182 %r = icmp eq i32 %and, 0183 ret i1 %r184}185 186; X is constant187 188define i1 @scalar_i32_signbit_lshr_and_eq_X_is_constant1(i32 %y) {189; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq_X_is_constant1(190; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]191; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], 12345192; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0193; CHECK-NEXT: ret i1 [[R]]194;195 %lshr = lshr i32 2147483648, %y196 %and = and i32 %lshr, 12345197 %r = icmp eq i32 %and, 0198 ret i1 %r199}200 201define i1 @scalar_i32_signbit_lshr_and_eq_X_is_constant2(i32 %y) {202; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq_X_is_constant2(203; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[Y:%.*]], 31204; CHECK-NEXT: ret i1 [[TMP1]]205;206 %lshr = lshr i32 2147483648, %y207 %and = and i32 %lshr, 1208 %r = icmp eq i32 %and, 0209 ret i1 %r210}211 212; Negative tests213 214; Check 'slt' predicate215 216define i1 @scalar_i32_signbit_lshr_and_slt(i32 %x, i32 %y) {217; CHECK-LABEL: @scalar_i32_signbit_lshr_and_slt(218; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]219; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]220; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[AND]], 0221; CHECK-NEXT: ret i1 [[R]]222;223 %lshr = lshr i32 2147483648, %y224 %and = and i32 %lshr, %x225 %r = icmp slt i32 %and, 0226 ret i1 %r227}228 229; Compare with nonzero230 231define i1 @scalar_i32_signbit_lshr_and_eq_nonzero(i32 %x, i32 %y) {232; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq_nonzero(233; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]234; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]235; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 1236; CHECK-NEXT: ret i1 [[R]]237;238 %lshr = lshr i32 2147483648, %y239 %and = and i32 %lshr, %x240 %r = icmp eq i32 %and, 1 ; should be comparing with 0241 ret i1 %r242}243