229 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 << Y) & signbit) ==/!= 05; it may be optimal to fold into (X << Y) >=/< 06; rather than X & (signbit l>> Y) ==/!= 07 8; Scalar tests9 10define i1 @scalar_i8_shl_and_signbit_eq(i8 %x, i8 %y) {11; CHECK-LABEL: @scalar_i8_shl_and_signbit_eq(12; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], [[Y:%.*]]13; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[SHL]], -114; CHECK-NEXT: ret i1 [[R]]15;16 %shl = shl i8 %x, %y17 %and = and i8 %shl, 12818 %r = icmp eq i8 %and, 019 ret i1 %r20}21 22define i1 @scalar_i16_shl_and_signbit_eq(i16 %x, i16 %y) {23; CHECK-LABEL: @scalar_i16_shl_and_signbit_eq(24; CHECK-NEXT: [[SHL:%.*]] = shl i16 [[X:%.*]], [[Y:%.*]]25; CHECK-NEXT: [[R:%.*]] = icmp sgt i16 [[SHL]], -126; CHECK-NEXT: ret i1 [[R]]27;28 %shl = shl i16 %x, %y29 %and = and i16 %shl, 3276830 %r = icmp eq i16 %and, 031 ret i1 %r32}33 34define i1 @scalar_i32_shl_and_signbit_eq(i32 %x, i32 %y) {35; CHECK-LABEL: @scalar_i32_shl_and_signbit_eq(36; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]37; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[SHL]], -138; CHECK-NEXT: ret i1 [[R]]39;40 %shl = shl i32 %x, %y41 %and = and i32 %shl, 214748364842 %r = icmp eq i32 %and, 043 ret i1 %r44}45 46define i1 @scalar_i64_shl_and_signbit_eq(i64 %x, i64 %y) {47; CHECK-LABEL: @scalar_i64_shl_and_signbit_eq(48; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X:%.*]], [[Y:%.*]]49; CHECK-NEXT: [[R:%.*]] = icmp sgt i64 [[SHL]], -150; CHECK-NEXT: ret i1 [[R]]51;52 %shl = shl i64 %x, %y53 %and = and i64 %shl, 922337203685477580854 %r = icmp eq i64 %and, 055 ret i1 %r56}57 58define i1 @scalar_i32_shl_and_signbit_ne(i32 %x, i32 %y) {59; CHECK-LABEL: @scalar_i32_shl_and_signbit_ne(60; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]61; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[SHL]], 062; CHECK-NEXT: ret i1 [[R]]63;64 %shl = shl i32 %x, %y65 %and = and i32 %shl, 214748364866 %r = icmp ne i32 %and, 0 ; check 'ne' predicate67 ret i1 %r68}69 70; Vector tests71 72define <4 x i1> @vec_4xi32_shl_and_signbit_eq(<4 x i32> %x, <4 x i32> %y) {73; CHECK-LABEL: @vec_4xi32_shl_and_signbit_eq(74; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]]75; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[SHL]], splat (i32 -1)76; CHECK-NEXT: ret <4 x i1> [[R]]77;78 %shl = shl <4 x i32> %x, %y79 %and = and <4 x i32> %shl, <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648>80 %r = icmp eq <4 x i32> %and, <i32 0, i32 0, i32 0, i32 0>81 ret <4 x i1> %r82}83 84define <4 x i1> @vec_4xi32_shl_and_signbit_eq_poison1(<4 x i32> %x, <4 x i32> %y) {85; CHECK-LABEL: @vec_4xi32_shl_and_signbit_eq_poison1(86; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]]87; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[SHL]], splat (i32 -1)88; CHECK-NEXT: ret <4 x i1> [[R]]89;90 %shl = shl <4 x i32> %x, %y91 %and = and <4 x i32> %shl, <i32 2147483648, i32 poison, i32 2147483648, i32 2147483648>92 %r = icmp eq <4 x i32> %and, <i32 0, i32 0, i32 0, i32 0>93 ret <4 x i1> %r94}95 96define <4 x i1> @vec_4xi32_shl_and_signbit_eq_poison2(<4 x i32> %x, <4 x i32> %y) {97; CHECK-LABEL: @vec_4xi32_shl_and_signbit_eq_poison2(98; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]]99; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[SHL]], splat (i32 -1)100; CHECK-NEXT: ret <4 x i1> [[R]]101;102 %shl = shl <4 x i32> %x, %y103 %and = and <4 x i32> %shl, <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648>104 %r = icmp eq <4 x i32> %and, <i32 poison, i32 0, i32 0, i32 0>105 ret <4 x i1> %r106}107 108define <4 x i1> @vec_4xi32_shl_and_signbit_eq_poison3(<4 x i32> %x, <4 x i32> %y) {109; CHECK-LABEL: @vec_4xi32_shl_and_signbit_eq_poison3(110; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]]111; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[SHL]], splat (i32 -1)112; CHECK-NEXT: ret <4 x i1> [[R]]113;114 %shl = shl <4 x i32> %x, %y115 %and = and <4 x i32> %shl, <i32 2147483648, i32 poison, i32 2147483648, i32 2147483648>116 %r = icmp eq <4 x i32> %and, <i32 0, i32 0, i32 0, i32 poison>117 ret <4 x i1> %r118}119 120; Extra use121 122; Fold happened123define i1 @scalar_shl_and_signbit_eq_extra_use_shl(i32 %x, i32 %y, i32 %z, ptr %p) {124; CHECK-LABEL: @scalar_shl_and_signbit_eq_extra_use_shl(125; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]126; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[SHL]], [[Z:%.*]]127; CHECK-NEXT: store i32 [[XOR]], ptr [[P:%.*]], align 4128; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[SHL]], -1129; CHECK-NEXT: ret i1 [[R]]130;131 %shl = shl i32 %x, %y132 %xor = xor i32 %shl, %z ; extra use of shl133 store i32 %xor, ptr %p134 %and = and i32 %shl, 2147483648135 %r = icmp eq i32 %and, 0136 ret i1 %r137}138 139; Not fold140define i1 @scalar_shl_and_signbit_eq_extra_use_and(i32 %x, i32 %y, i32 %z, ptr %p) {141; CHECK-LABEL: @scalar_shl_and_signbit_eq_extra_use_and(142; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]143; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], -2147483648144; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[AND]], [[Z:%.*]]145; CHECK-NEXT: store i32 [[MUL]], ptr [[P:%.*]], align 4146; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0147; CHECK-NEXT: ret i1 [[R]]148;149 %shl = shl i32 %x, %y150 %and = and i32 %shl, 2147483648151 %mul = mul i32 %and, %z ; extra use of and152 store i32 %mul, ptr %p153 %r = icmp eq i32 %and, 0154 ret i1 %r155}156 157; Not fold158define i1 @scalar_shl_and_signbit_eq_extra_use_shl_and(i32 %x, i32 %y, i32 %z, ptr %p, ptr %q) {159; CHECK-LABEL: @scalar_shl_and_signbit_eq_extra_use_shl_and(160; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]161; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], -2147483648162; CHECK-NEXT: store i32 [[AND]], ptr [[P:%.*]], align 4163; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SHL]], [[Z:%.*]]164; CHECK-NEXT: store i32 [[ADD]], ptr [[Q:%.*]], align 4165; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0166; CHECK-NEXT: ret i1 [[R]]167;168 %shl = shl i32 %x, %y169 %and = and i32 %shl, 2147483648170 store i32 %and, ptr %p ; extra use of and171 %add = add i32 %shl, %z ; extra use of shl172 store i32 %add, ptr %q173 %r = icmp eq i32 %and, 0174 ret i1 %r175}176 177; Negative tests178 179; X is constant180 181define i1 @scalar_i32_shl_and_signbit_eq_X_is_constant1(i32 %y) {182; CHECK-LABEL: @scalar_i32_shl_and_signbit_eq_X_is_constant1(183; CHECK-NEXT: [[SHL:%.*]] = shl i32 12345, [[Y:%.*]]184; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[SHL]], -1185; CHECK-NEXT: ret i1 [[R]]186;187 %shl = shl i32 12345, %y188 %and = and i32 %shl, 2147483648189 %r = icmp eq i32 %and, 0190 ret i1 %r191}192 193define i1 @scalar_i32_shl_and_signbit_eq_X_is_constant2(i32 %y) {194; CHECK-LABEL: @scalar_i32_shl_and_signbit_eq_X_is_constant2(195; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[Y:%.*]], 31196; CHECK-NEXT: ret i1 [[TMP1]]197;198 %shl = shl i32 1, %y199 %and = and i32 %shl, 2147483648200 %r = icmp eq i32 %and, 0201 ret i1 %r202}203 204; Check 'slt' predicate205 206define i1 @scalar_i32_shl_and_signbit_slt(i32 %x, i32 %y) {207; CHECK-LABEL: @scalar_i32_shl_and_signbit_slt(208; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]209; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[SHL]], 0210; CHECK-NEXT: ret i1 [[R]]211;212 %shl = shl i32 %x, %y213 %and = and i32 %shl, 2147483648214 %r = icmp slt i32 %and, 0215 ret i1 %r216}217 218; Compare with nonzero219 220define i1 @scalar_i32_shl_and_signbit_eq_nonzero(i32 %x, i32 %y) {221; CHECK-LABEL: @scalar_i32_shl_and_signbit_eq_nonzero(222; CHECK-NEXT: ret i1 false223;224 %shl = shl i32 %x, %y225 %and = and i32 %shl, 2147483648226 %r = icmp eq i32 %and, 1 ; should be comparing with 0227 ret i1 %r228}229