Skip to content

Commit c1ee93b

Browse files
committed
Apply transformation
1 parent d228da4 commit c1ee93b

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7687,6 +7687,30 @@ 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 PredEq = ICmpInst::ICMP_EQ;
7694+
if (I.getPredicate() == PredEq) {
7695+
// c2 must be positive
7696+
// sext(a) & c1 == c2 --> a & c3 == trunc(c2)
7697+
if (match(Op0, m_And(m_SExtLike(m_Value(A)), m_APInt(C1))) && match(Op1, m_APInt(C2))) {
7698+
if (C2->isNonNegative()) {
7699+
Type *InputTy = A->getType();
7700+
unsigned TargetBitSize = InputTy->getScalarSizeInBits();
7701+
// Count the number of 1s in C1 high bits of size TargetBitSize.
7702+
unsigned Leading1sCount = C1->lshr(C1->getBitWidth() - TargetBitSize).popcount();
7703+
APInt TruncC1 = C1->trunc(TargetBitSize);
7704+
if (Leading1sCount > 0) {
7705+
TruncC1.setBit(TargetBitSize - 1);
7706+
}
7707+
Value *AndInst = Builder.CreateAnd(A, TruncC1);
7708+
return new ICmpInst(PredEq, AndInst, ConstantInt::get(InputTy, C2->trunc(TargetBitSize)));
7709+
}
7710+
}
7711+
}
7712+
}
7713+
76907714
return Changed ? &I : nullptr;
76917715
}
76927716

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

Lines changed: 6 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
@@ -22,8 +21,8 @@ define i1 @fold_sext_to_and_multi_use(i8 %x) {
2221
; CHECK-SAME: i8 [[X:%.*]]) {
2322
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
2423
; CHECK-NEXT: call void @use(i32 [[TMP1]])
25-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -2147483647
26-
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
24+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X]], -127
25+
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], 1
2726
; CHECK-NEXT: ret i1 [[TMP3]]
2827
;
2928
%1 = sext i8 %x to i32
@@ -37,11 +36,8 @@ define i1 @fold_sext_to_and_multi_use(i8 %x) {
3736

3837
define i1 @fold_sext_to_and_wrong(i8 %x) {
3938
; CHECK-LABEL: define i1 @fold_sext_to_and_wrong(
40-
; CHECK-SAME: i2 [[X:%.*]]) {
41-
; CHECK-NEXT: [[TMP1:%.*]] = sext i2 [[X]] to i32
42-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -2147483647
43-
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
44-
; CHECK-NEXT: ret i1 [[TMP3]]
39+
; CHECK-SAME: i8 [[X:%.*]]) {
40+
; CHECK-NEXT: ret i1 false
4541
;
4642
%1 = sext i8 %x to i32
4743
%2 = and i32 %1, -2147483647

0 commit comments

Comments
 (0)