227 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 l>> Y) & signbit) ==/!= 05; it may be optimal to fold into (X l>> Y) >=/< 06; rather than X & (signbit << Y) ==/!= 07 8; Scalar tests9 10define i1 @scalar_i8_lshr_and_signbit_eq(i8 %x, i8 %y) {11; CHECK-LABEL: @scalar_i8_lshr_and_signbit_eq(12; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 [[X:%.*]], [[Y:%.*]]13; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[LSHR]], -114; CHECK-NEXT: ret i1 [[R]]15;16 %lshr = lshr i8 %x, %y17 %and = and i8 %lshr, 12818 %r = icmp eq i8 %and, 019 ret i1 %r20}21 22define i1 @scalar_i16_lshr_and_signbit_eq(i16 %x, i16 %y) {23; CHECK-LABEL: @scalar_i16_lshr_and_signbit_eq(24; CHECK-NEXT: [[LSHR:%.*]] = lshr i16 [[X:%.*]], [[Y:%.*]]25; CHECK-NEXT: [[R:%.*]] = icmp sgt i16 [[LSHR]], -126; CHECK-NEXT: ret i1 [[R]]27;28 %lshr = lshr i16 %x, %y29 %and = and i16 %lshr, 3276830 %r = icmp eq i16 %and, 031 ret i1 %r32}33 34define i1 @scalar_i32_lshr_and_signbit_eq(i32 %x, i32 %y) {35; CHECK-LABEL: @scalar_i32_lshr_and_signbit_eq(36; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]37; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[LSHR]], -138; CHECK-NEXT: ret i1 [[R]]39;40 %lshr = lshr i32 %x, %y41 %and = and i32 %lshr, 214748364842 %r = icmp eq i32 %and, 043 ret i1 %r44}45 46define i1 @scalar_i64_lshr_and_signbit_eq(i64 %x, i64 %y) {47; CHECK-LABEL: @scalar_i64_lshr_and_signbit_eq(48; CHECK-NEXT: [[LSHR:%.*]] = lshr i64 [[X:%.*]], [[Y:%.*]]49; CHECK-NEXT: [[R:%.*]] = icmp sgt i64 [[LSHR]], -150; CHECK-NEXT: ret i1 [[R]]51;52 %lshr = lshr i64 %x, %y53 %and = and i64 %lshr, 922337203685477580854 %r = icmp eq i64 %and, 055 ret i1 %r56}57 58define i1 @scalar_i32_lshr_and_signbit_ne(i32 %x, i32 %y) {59; CHECK-LABEL: @scalar_i32_lshr_and_signbit_ne(60; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]61; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[LSHR]], 062; CHECK-NEXT: ret i1 [[R]]63;64 %lshr = lshr i32 %x, %y65 %and = and i32 %lshr, 214748364866 %r = icmp ne i32 %and, 0 ; check 'ne' predicate67 ret i1 %r68}69 70; Vector tests71 72define <4 x i1> @vec_4xi32_lshr_and_signbit_eq(<4 x i32> %x, <4 x i32> %y) {73; CHECK-LABEL: @vec_4xi32_lshr_and_signbit_eq(74; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]]75; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[LSHR]], splat (i32 -1)76; CHECK-NEXT: ret <4 x i1> [[R]]77;78 %lshr = lshr <4 x i32> %x, %y79 %and = and <4 x i32> %lshr, <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_lshr_and_signbit_eq_poison1(<4 x i32> %x, <4 x i32> %y) {85; CHECK-LABEL: @vec_4xi32_lshr_and_signbit_eq_poison1(86; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]]87; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[LSHR]], splat (i32 -1)88; CHECK-NEXT: ret <4 x i1> [[R]]89;90 %lshr = lshr <4 x i32> %x, %y91 %and = and <4 x i32> %lshr, <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_lshr_and_signbit_eq_poison2(<4 x i32> %x, <4 x i32> %y) {97; CHECK-LABEL: @vec_4xi32_lshr_and_signbit_eq_poison2(98; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]]99; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[LSHR]], splat (i32 -1)100; CHECK-NEXT: ret <4 x i1> [[R]]101;102 %lshr = lshr <4 x i32> %x, %y103 %and = and <4 x i32> %lshr, <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_lshr_and_signbit_eq_poison3(<4 x i32> %x, <4 x i32> %y) {109; CHECK-LABEL: @vec_4xi32_lshr_and_signbit_eq_poison3(110; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]]111; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[LSHR]], splat (i32 -1)112; CHECK-NEXT: ret <4 x i1> [[R]]113;114 %lshr = lshr <4 x i32> %x, %y115 %and = and <4 x i32> %lshr, <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_lshr_and_signbit_eq_extra_use_lshr(i32 %x, i32 %y, i32 %z, ptr %p) {124; CHECK-LABEL: @scalar_lshr_and_signbit_eq_extra_use_lshr(125; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]126; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[LSHR]], [[Z:%.*]]127; CHECK-NEXT: store i32 [[XOR]], ptr [[P:%.*]], align 4128; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[LSHR]], -1129; CHECK-NEXT: ret i1 [[R]]130;131 %lshr = lshr i32 %x, %y132 %xor = xor i32 %lshr, %z ; extra use of lshr133 store i32 %xor, ptr %p134 %and = and i32 %lshr, 2147483648135 %r = icmp eq i32 %and, 0136 ret i1 %r137}138 139; Not fold140define i1 @scalar_lshr_and_signbit_eq_extra_use_and(i32 %x, i32 %y, i32 %z, ptr %p) {141; CHECK-LABEL: @scalar_lshr_and_signbit_eq_extra_use_and(142; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]143; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], -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 %lshr = lshr i32 %x, %y150 %and = and i32 %lshr, 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_lshr_and_signbit_eq_extra_use_lshr_and(i32 %x, i32 %y, i32 %z, ptr %p, ptr %q) {159; CHECK-LABEL: @scalar_lshr_and_signbit_eq_extra_use_lshr_and(160; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]161; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], -2147483648162; CHECK-NEXT: store i32 [[AND]], ptr [[P:%.*]], align 4163; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LSHR]], [[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 %lshr = lshr i32 %x, %y169 %and = and i32 %lshr, 2147483648170 store i32 %and, ptr %p ; extra use of and171 %add = add i32 %lshr, %z ; extra use of lshr172 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_lshr_and_signbit_eq_X_is_constant1(i32 %y) {182; CHECK-LABEL: @scalar_i32_lshr_and_signbit_eq_X_is_constant1(183; CHECK-NEXT: ret i1 true184;185 %lshr = lshr i32 12345, %y186 %and = and i32 %lshr, 2147483648187 %r = icmp eq i32 %and, 0188 ret i1 %r189}190 191define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant2(i32 %y) {192; CHECK-LABEL: @scalar_i32_lshr_and_negC_eq_X_is_constant2(193; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[Y:%.*]], 0194; CHECK-NEXT: ret i1 [[TMP1]]195;196 %lshr = lshr i32 2147483648, %y197 %and = and i32 %lshr, 2147483648198 %r = icmp eq i32 %and, 0199 ret i1 %r200}201 202; Check 'slt' predicate203 204define i1 @scalar_i32_lshr_and_negC_slt(i32 %x, i32 %y) {205; CHECK-LABEL: @scalar_i32_lshr_and_negC_slt(206; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]207; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[LSHR]], 0208; CHECK-NEXT: ret i1 [[R]]209;210 %lshr = lshr i32 %x, %y211 %and = and i32 %lshr, 2147483648212 %r = icmp slt i32 %and, 0213 ret i1 %r214}215 216; Compare with nonzero217 218define i1 @scalar_i32_lshr_and_negC_eq_nonzero(i32 %x, i32 %y) {219; CHECK-LABEL: @scalar_i32_lshr_and_negC_eq_nonzero(220; CHECK-NEXT: ret i1 false221;222 %lshr = lshr i32 %x, %y223 %and = and i32 %lshr, 2147483648224 %r = icmp eq i32 %and, 1 ; should be comparing with 0225 ret i1 %r226}227