Skip to content

Commit c20fa0e

Browse files
committed
Apply transformation
1 parent f82f372 commit c20fa0e

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
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_SExtLike(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->ult(APInt::getOneBitSet(C2->getBitWidth(), 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/sext-and.ll

Lines changed: 8 additions & 10 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
@@ -36,8 +34,8 @@ define i1 @fold_sext_to_and_multi_use(i8 %x) {
3634
; CHECK-SAME: i8 [[X:%.*]]) {
3735
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
3836
; CHECK-NEXT: call void @use(i32 [[TMP1]])
39-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -2147483647
40-
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
37+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X]], -127
38+
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], 1
4139
; CHECK-NEXT: ret i1 [[TMP3]]
4240
;
4341
%1 = sext i8 %x to i32
@@ -52,8 +50,8 @@ define i1 @fold_sext_to_and_multi_use1(i8 %x) {
5250
; CHECK-SAME: i8 [[X:%.*]]) {
5351
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
5452
; CHECK-NEXT: call void @use(i32 [[TMP1]])
55-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -2147483647
56-
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 1
53+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X]], -127
54+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], 1
5755
; CHECK-NEXT: ret i1 [[TMP3]]
5856
;
5957
%1 = sext i8 %x to i32

0 commit comments

Comments
 (0)