Skip to content

Commit 3d97acf

Browse files
committed
Apply transformation
1 parent ab5fac9 commit 3d97acf

File tree

2 files changed

+38
-10
lines changed

2 files changed

+38
-10
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "InstCombineInternal.h"
14+
#include "llvm/ADT/APInt.h"
1415
#include "llvm/ADT/APSInt.h"
1516
#include "llvm/ADT/ScopeExit.h"
1617
#include "llvm/ADT/SetVector.h"
@@ -24,6 +25,7 @@
2425
#include "llvm/IR/ConstantRange.h"
2526
#include "llvm/IR/DataLayout.h"
2627
#include "llvm/IR/InstrTypes.h"
28+
#include "llvm/IR/Instructions.h"
2729
#include "llvm/IR/IntrinsicInst.h"
2830
#include "llvm/IR/PatternMatch.h"
2931
#include "llvm/Support/KnownBits.h"
@@ -7687,6 +7689,34 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
76877689
if (Instruction *Res = foldReductionIdiom(I, Builder, DL))
76887690
return Res;
76897691

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

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)