236 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 << Y)) ==/!= 05; it may be optimal to fold into (X l>> Y) >=/< 06 7; Scalar tests8 9define i1 @scalar_i8_signbit_shl_and_eq(i8 %x, i8 %y) {10; CHECK-LABEL: @scalar_i8_signbit_shl_and_eq(11; CHECK-NEXT: [[SHL:%.*]] = shl i8 -128, [[Y:%.*]]12; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHL]], [[X:%.*]]13; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 014; CHECK-NEXT: ret i1 [[R]]15;16 %shl = shl i8 128, %y17 %and = and i8 %shl, %x18 %r = icmp eq i8 %and, 019 ret i1 %r20}21 22define i1 @scalar_i16_signbit_shl_and_eq(i16 %x, i16 %y) {23; CHECK-LABEL: @scalar_i16_signbit_shl_and_eq(24; CHECK-NEXT: [[SHL:%.*]] = shl i16 -32768, [[Y:%.*]]25; CHECK-NEXT: [[AND:%.*]] = and i16 [[SHL]], [[X:%.*]]26; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[AND]], 027; CHECK-NEXT: ret i1 [[R]]28;29 %shl = shl i16 32768, %y30 %and = and i16 %shl, %x31 %r = icmp eq i16 %and, 032 ret i1 %r33}34 35define i1 @scalar_i32_signbit_shl_and_eq(i32 %x, i32 %y) {36; CHECK-LABEL: @scalar_i32_signbit_shl_and_eq(37; CHECK-NEXT: [[SHL:%.*]] = shl i32 -2147483648, [[Y:%.*]]38; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], [[X:%.*]]39; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 040; CHECK-NEXT: ret i1 [[R]]41;42 %shl = shl i32 2147483648, %y43 %and = and i32 %shl, %x44 %r = icmp eq i32 %and, 045 ret i1 %r46}47 48define i1 @scalar_i64_signbit_shl_and_eq(i64 %x, i64 %y) {49; CHECK-LABEL: @scalar_i64_signbit_shl_and_eq(50; CHECK-NEXT: [[SHL:%.*]] = shl i64 -9223372036854775808, [[Y:%.*]]51; CHECK-NEXT: [[AND:%.*]] = and i64 [[SHL]], [[X:%.*]]52; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[AND]], 053; CHECK-NEXT: ret i1 [[R]]54;55 %shl = shl i64 9223372036854775808, %y56 %and = and i64 %shl, %x57 %r = icmp eq i64 %and, 058 ret i1 %r59}60 61define i1 @scalar_i32_signbit_shl_and_ne(i32 %x, i32 %y) {62; CHECK-LABEL: @scalar_i32_signbit_shl_and_ne(63; CHECK-NEXT: [[SHL:%.*]] = shl i32 -2147483648, [[Y:%.*]]64; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], [[X:%.*]]65; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[AND]], 066; CHECK-NEXT: ret i1 [[R]]67;68 %shl = shl i32 2147483648, %y69 %and = and i32 %shl, %x70 %r = icmp ne i32 %and, 0 ; check 'ne' predicate71 ret i1 %r72}73 74; Vector tests75 76define <4 x i1> @vec_4xi32_signbit_shl_and_eq(<4 x i32> %x, <4 x i32> %y) {77; CHECK-LABEL: @vec_4xi32_signbit_shl_and_eq(78; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> splat (i32 -2147483648), [[Y:%.*]]79; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], [[X:%.*]]80; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], zeroinitializer81; CHECK-NEXT: ret <4 x i1> [[R]]82;83 %shl = shl <4 x i32> <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648>, %y84 %and = and <4 x i32> %shl, %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_shl_and_eq_undef1(<4 x i32> %x, <4 x i32> %y) {90; CHECK-LABEL: @vec_4xi32_signbit_shl_and_eq_undef1(91; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> <i32 -2147483648, i32 undef, i32 -2147483648, i32 2147473648>, [[Y:%.*]]92; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], [[X:%.*]]93; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], zeroinitializer94; CHECK-NEXT: ret <4 x i1> [[R]]95;96 %shl = shl <4 x i32> <i32 2147483648, i32 undef, i32 2147483648, i32 2147473648>, %y97 %and = and <4 x i32> %shl, %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_shl_and_eq_undef2(<4 x i32> %x, <4 x i32> %y) {103; CHECK-LABEL: @vec_4xi32_signbit_shl_and_eq_undef2(104; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 2147473648>, [[Y:%.*]]105; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], [[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 %shl = shl <4 x i32> <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147473648>, %y110 %and = and <4 x i32> %shl, %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_shl_and_eq_undef3(<4 x i32> %x, <4 x i32> %y) {116; CHECK-LABEL: @vec_4xi32_signbit_shl_and_eq_undef3(117; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> <i32 -2147483648, i32 undef, i32 -2147483648, i32 2147473648>, [[Y:%.*]]118; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], [[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 %shl = shl <4 x i32> <i32 2147483648, i32 undef, i32 2147483648, i32 2147473648>, %y123 %and = and <4 x i32> %shl, %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_shl_and_eq_extra_use_shl(i32 %x, i32 %y, i32 %z, ptr %p) {132; CHECK-LABEL: @scalar_i32_signbit_shl_and_eq_extra_use_shl(133; CHECK-NEXT: [[SHL:%.*]] = shl i32 -2147483648, [[Y:%.*]]134; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[SHL]], [[Z:%.*]]135; CHECK-NEXT: store i32 [[XOR]], ptr [[P:%.*]], align 4136; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], [[X:%.*]]137; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0138; CHECK-NEXT: ret i1 [[R]]139;140 %shl = shl i32 2147483648, %y141 %xor = xor i32 %shl, %z ; extra use of shl142 store i32 %xor, ptr %p143 %and = and i32 %shl, %x144 %r = icmp eq i32 %and, 0145 ret i1 %r146}147 148; Not fold149define i1 @scalar_i32_signbit_shl_and_eq_extra_use_and(i32 %x, i32 %y, i32 %z, ptr %p) {150; CHECK-LABEL: @scalar_i32_signbit_shl_and_eq_extra_use_and(151; CHECK-NEXT: [[SHL:%.*]] = shl i32 -2147483648, [[Y:%.*]]152; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], [[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 %shl = shl i32 2147483648, %y159 %and = and i32 %shl, %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_shl_and_eq_extra_use_shl_and(i32 %x, i32 %y, i32 %z, ptr %p, ptr %q) {168; CHECK-LABEL: @scalar_i32_signbit_shl_and_eq_extra_use_shl_and(169; CHECK-NEXT: [[SHL:%.*]] = shl i32 -2147483648, [[Y:%.*]]170; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], [[X:%.*]]171; CHECK-NEXT: store i32 [[AND]], ptr [[P:%.*]], align 4172; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SHL]], [[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 %shl = shl i32 2147483648, %y178 %and = and i32 %shl, %x179 store i32 %and, ptr %p ; extra use of and180 %add = add i32 %shl, %z ; extra use of shl181 store i32 %add, ptr %q182 %r = icmp eq i32 %and, 0183 ret i1 %r184}185 186; X is constant187 188define i1 @scalar_i32_signbit_shl_and_eq_X_is_constant1(i32 %y) {189; CHECK-LABEL: @scalar_i32_signbit_shl_and_eq_X_is_constant1(190; CHECK-NEXT: ret i1 true191;192 %shl = shl i32 2147483648, %y193 %and = and i32 %shl, 12345194 %r = icmp eq i32 %and, 0195 ret i1 %r196}197 198define i1 @scalar_i32_signbit_shl_and_eq_X_is_constant2(i32 %y) {199; CHECK-LABEL: @scalar_i32_signbit_shl_and_eq_X_is_constant2(200; CHECK-NEXT: ret i1 true201;202 %shl = shl i32 2147483648, %y203 %and = and i32 %shl, 1204 %r = icmp eq i32 %and, 0205 ret i1 %r206}207 208; Negative tests209 210; Check 'slt' predicate211 212define i1 @scalar_i32_signbit_shl_and_slt(i32 %x, i32 %y) {213; CHECK-LABEL: @scalar_i32_signbit_shl_and_slt(214; CHECK-NEXT: [[SHL:%.*]] = shl i32 -2147483648, [[Y:%.*]]215; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], [[X:%.*]]216; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[AND]], 0217; CHECK-NEXT: ret i1 [[R]]218;219 %shl = shl i32 2147483648, %y220 %and = and i32 %shl, %x221 %r = icmp slt i32 %and, 0222 ret i1 %r223}224 225; Compare with nonzero226 227define i1 @scalar_i32_signbit_shl_and_eq_nonzero(i32 %x, i32 %y) {228; CHECK-LABEL: @scalar_i32_signbit_shl_and_eq_nonzero(229; CHECK-NEXT: ret i1 false230;231 %shl = shl i32 2147483648, %y232 %and = and i32 %shl, %x233 %r = icmp eq i32 %and, 1 ; should be comparing with 0234 ret i1 %r235}236