Skip to content

Commit 9110bbd

Browse files
committed
Apply transformation
1 parent ab5fac9 commit 9110bbd

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
@@ -7687,6 +7687,32 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
76877687
if (Instruction *Res = foldReductionIdiom(I, Builder, DL))
76887688
return Res;
76897689

7690+
{
7691+
Value *A;
7692+
const APInt *C1, *C2;
7693+
ICmpInst::Predicate Pred = I.getPredicate();
7694+
if (ICmpInst::isEquality(Pred)) {
7695+
// sext(a) & c1 == c2 --> a & c3 == trunc(c2)
7696+
// sext(a) & c1 != c2 --> a & c3 != trunc(c2)
7697+
if (match(Op0, m_And(m_SExtLike(m_Value(A)), m_APInt(C1))) &&
7698+
match(Op1, m_APInt(C2))) {
7699+
Type *InputTy = A->getType();
7700+
unsigned InputBitWidth = InputTy->getScalarSizeInBits();
7701+
// c2 must be non-negative at the bitwidth of a.
7702+
if (C2->ult(APInt::getOneBitSet(C2->getBitWidth(), InputBitWidth))) {
7703+
APInt TruncC1 = C1->trunc(InputBitWidth);
7704+
// Check if there are 1s in C1 high bits of size InputBitWidth.
7705+
if (C1->uge(APInt::getOneBitSet(C1->getBitWidth(), InputBitWidth)))
7706+
TruncC1.setBit(InputBitWidth - 1);
7707+
Value *AndInst = Builder.CreateAnd(A, TruncC1);
7708+
return new ICmpInst(
7709+
Pred, AndInst,
7710+
ConstantInt::get(InputTy, C2->trunc(InputBitWidth)));
7711+
}
7712+
}
7713+
}
7714+
}
7715+
76907716
return Changed ? &I : nullptr;
76917717
}
76927718

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)