Skip to content

Commit 1ddd277

Browse files
committed
Apply transformation
1 parent 1eaac25 commit 1ddd277

File tree

3 files changed

+43
-23
lines changed

3 files changed

+43
-23
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7716,6 +7716,32 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
77167716
if (Instruction *Res = foldReductionIdiom(I, Builder, DL))
77177717
return Res;
77187718

7719+
{
7720+
Value *A;
7721+
const APInt *C1, *C2;
7722+
ICmpInst::Predicate Pred = I.getPredicate();
7723+
if (ICmpInst::isEquality(Pred)) {
7724+
// sext(a) & c1 == c2 --> a & c3 == trunc(c2)
7725+
// sext(a) & c1 != c2 --> a & c3 != trunc(c2)
7726+
if (match(Op0, m_And(m_SExt(m_Value(A)), m_APInt(C1))) &&
7727+
match(Op1, m_APInt(C2))) {
7728+
Type *InputTy = A->getType();
7729+
unsigned InputBitWidth = InputTy->getScalarSizeInBits();
7730+
// c2 must be non-negative at the bitwidth of a.
7731+
if (C2->getActiveBits() < InputBitWidth) {
7732+
APInt TruncC1 = C1->trunc(InputBitWidth);
7733+
// Check if there are 1s in C1 high bits of size InputBitWidth.
7734+
if (C1->uge(APInt::getOneBitSet(C1->getBitWidth(), InputBitWidth)))
7735+
TruncC1.setBit(InputBitWidth - 1);
7736+
Value *AndInst = Builder.CreateAnd(A, TruncC1);
7737+
return new ICmpInst(
7738+
Pred, AndInst,
7739+
ConstantInt::get(InputTy, C2->trunc(InputBitWidth)));
7740+
}
7741+
}
7742+
}
7743+
}
7744+
77197745
return Changed ? &I : nullptr;
77207746
}
77217747

llvm/test/Transforms/InstCombine/load-cmp.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,7 @@ define i1 @test10_struct_arr_i64(i64 %x) {
312312

313313
define i1 @test10_struct_arr_noinbounds_i16(i16 %x) {
314314
; CHECK-LABEL: @test10_struct_arr_noinbounds_i16(
315-
; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[X:%.*]] to i32
316-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 268435455
317-
; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[TMP2]], 1
315+
; CHECK-NEXT: [[R:%.*]] = icmp ne i16 [[X:%.*]], 1
318316
; CHECK-NEXT: ret i1 [[R]]
319317
;
320318
%p = getelementptr [4 x %Foo], ptr @GStructArr, i32 0, i16 %x, i32 2

llvm/test/Transforms/InstCombine/sext-and.ll

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ declare void @use(i8)
66
define i1 @fold_sext_to_and(i8 %x) {
77
; CHECK-LABEL: define i1 @fold_sext_to_and(
88
; CHECK-SAME: i8 [[X:%.*]]) {
9-
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
10-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -2147483647
11-
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
9+
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -127
10+
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP1]], 1
1211
; CHECK-NEXT: ret i1 [[TMP3]]
1312
;
1413
%1 = sext i8 %x to i32
@@ -20,9 +19,8 @@ define i1 @fold_sext_to_and(i8 %x) {
2019
define i1 @fold_sext_to_and1(i8 %x) {
2120
; CHECK-LABEL: define i1 @fold_sext_to_and1(
2221
; CHECK-SAME: i8 [[X:%.*]]) {
23-
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
24-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -2147483647
25-
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 1
22+
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -127
23+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP1]], 1
2624
; CHECK-NEXT: ret i1 [[TMP3]]
2725
;
2826
%1 = sext i8 %x to i32
@@ -34,9 +32,8 @@ define i1 @fold_sext_to_and1(i8 %x) {
3432
define i1 @fold_sext_to_and2(i8 %x) {
3533
; CHECK-LABEL: define i1 @fold_sext_to_and2(
3634
; CHECK-SAME: i8 [[X:%.*]]) {
37-
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
38-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1073741826
39-
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 2
35+
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -126
36+
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP1]], 2
4037
; CHECK-NEXT: ret i1 [[TMP3]]
4138
;
4239
%1 = sext i8 %x to i32
@@ -48,9 +45,8 @@ define i1 @fold_sext_to_and2(i8 %x) {
4845
define i1 @fold_sext_to_and3(i8 %x) {
4946
; CHECK-LABEL: define i1 @fold_sext_to_and3(
5047
; CHECK-SAME: i8 [[X:%.*]]) {
51-
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
52-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1073741826
53-
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 2
48+
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -126
49+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP1]], 2
5450
; CHECK-NEXT: ret i1 [[TMP3]]
5551
;
5652
%1 = sext i8 %x to i32
@@ -64,8 +60,8 @@ define i1 @fold_sext_to_and_multi_use(i8 %x) {
6460
; CHECK-SAME: i8 [[X:%.*]]) {
6561
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
6662
; CHECK-NEXT: call void @use(i32 [[TMP1]])
67-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -2147483647
68-
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
63+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X]], -127
64+
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], 1
6965
; CHECK-NEXT: ret i1 [[TMP3]]
7066
;
7167
%1 = sext i8 %x to i32
@@ -80,8 +76,8 @@ define i1 @fold_sext_to_and_multi_use1(i8 %x) {
8076
; CHECK-SAME: i8 [[X:%.*]]) {
8177
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
8278
; CHECK-NEXT: call void @use(i32 [[TMP1]])
83-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -2147483647
84-
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 1
79+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X]], -127
80+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], 1
8581
; CHECK-NEXT: ret i1 [[TMP3]]
8682
;
8783
%1 = sext i8 %x to i32
@@ -96,8 +92,8 @@ define i1 @fold_sext_to_and_multi_use2(i8 %x) {
9692
; CHECK-SAME: i8 [[X:%.*]]) {
9793
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
9894
; CHECK-NEXT: call void @use(i32 [[TMP1]])
99-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1073741826
100-
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 2
95+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X]], -126
96+
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], 2
10197
; CHECK-NEXT: ret i1 [[TMP3]]
10298
;
10399
%1 = sext i8 %x to i32
@@ -112,8 +108,8 @@ define i1 @fold_sext_to_and_multi_use3(i8 %x) {
112108
; CHECK-SAME: i8 [[X:%.*]]) {
113109
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
114110
; CHECK-NEXT: call void @use(i32 [[TMP1]])
115-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1073741826
116-
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 2
111+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X]], -126
112+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], 2
117113
; CHECK-NEXT: ret i1 [[TMP3]]
118114
;
119115
%1 = sext i8 %x to i32

0 commit comments

Comments
 (0)