summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Analysis/CmpInstAnalysis.h3
-rw-r--r--llvm/lib/Analysis/CmpInstAnalysis.cpp13
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp13
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp2
-rw-r--r--llvm/test/Transforms/InstCombine/bit-checks.ll72
5 files changed, 37 insertions, 66 deletions
diff --git a/llvm/include/llvm/Analysis/CmpInstAnalysis.h b/llvm/include/llvm/Analysis/CmpInstAnalysis.h
index 1079d5abc7f..3cc69d9fea2 100644
--- a/llvm/include/llvm/Analysis/CmpInstAnalysis.h
+++ b/llvm/include/llvm/Analysis/CmpInstAnalysis.h
@@ -64,7 +64,8 @@ namespace llvm {
/// returned predicate is either == or !=. Returns false if decomposition
/// fails.
bool decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate &Pred,
- Value *&X, APInt &Mask);
+ Value *&X, APInt &Mask,
+ bool LookThroughTrunc = true);
} // end namespace llvm
diff --git a/llvm/lib/Analysis/CmpInstAnalysis.cpp b/llvm/lib/Analysis/CmpInstAnalysis.cpp
index c879b8729dc..159c1a2d135 100644
--- a/llvm/lib/Analysis/CmpInstAnalysis.cpp
+++ b/llvm/lib/Analysis/CmpInstAnalysis.cpp
@@ -66,9 +66,11 @@ bool llvm::PredicatesFoldable(ICmpInst::Predicate p1, ICmpInst::Predicate p2) {
bool llvm::decomposeBitTestICmp(Value *LHS, Value *RHS,
CmpInst::Predicate &Pred,
- Value *&X, APInt &Mask) {
+ Value *&X, APInt &Mask, bool LookThruTrunc) {
+ using namespace PatternMatch;
+
const APInt *C;
- if (!match(RHS, PatternMatch::m_APInt(C)))
+ if (!match(RHS, m_APInt(C)))
return false;
switch (Pred) {
@@ -132,6 +134,11 @@ bool llvm::decomposeBitTestICmp(Value *LHS, Value *RHS,
break;
}
- X = LHS;
+ if (LookThruTrunc && match(LHS, m_Trunc(m_Value(X)))) {
+ Mask = Mask.zext(X->getType()->getScalarSizeInBits());
+ } else {
+ X = LHS;
+ }
+
return true;
}
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index d155f6b4803..94d71817049 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3629,19 +3629,6 @@ static Value *simplifySelectWithFakeICmpEq(Value *CmpLHS, Value *CmpRHS,
if (!decomposeBitTestICmp(CmpLHS, CmpRHS, Pred, X, Mask))
return nullptr;
- unsigned BitWidth = TrueVal->getType()->getScalarSizeInBits();
- if (!BitWidth)
- return nullptr;
-
- Value *ExtX;
- if (match(X, m_Trunc(m_Value(ExtX))) &&
- (ExtX == TrueVal || ExtX == FalseVal)) {
- // icmp slt (trunc X), 0 <--> icmp ne (and X, C), 0
- // icmp sgt (trunc X), -1 <--> icmp eq (and X, C), 0
- X = ExtX;
- Mask = Mask.zext(BitWidth);
- }
-
return simplifySelectBitTest(TrueVal, FalseVal, X, &Mask,
Pred == ICmpInst::ICMP_EQ);
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 11602ab101e..83aeda5935e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -724,7 +724,7 @@ Instruction *InstCombiner::foldSelectInstWithICmp(SelectInst &SI,
ICmpInst::Predicate Pred = ICI->getPredicate();
Value *X;
APInt Mask;
- if (decomposeBitTestICmp(CmpLHS, CmpRHS, Pred, X, Mask)) {
+ if (decomposeBitTestICmp(CmpLHS, CmpRHS, Pred, X, Mask, false)) {
if (Mask.isSignMask()) {
assert(X == CmpLHS && "Expected to use the compare input directly");
assert(ICmpInst::isEquality(Pred) && "Expected equality predicate");
diff --git a/llvm/test/Transforms/InstCombine/bit-checks.ll b/llvm/test/Transforms/InstCombine/bit-checks.ll
index 3be67690431..1ecd305e807 100644
--- a/llvm/test/Transforms/InstCombine/bit-checks.ll
+++ b/llvm/test/Transforms/InstCombine/bit-checks.ll
@@ -520,12 +520,9 @@ define i32 @main7g(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
define i32 @main8(i32 %argc) {
; CHECK-LABEL: @main8(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[ARGC:%.*]], 64
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 0
-; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i32 [[ARGC]] to i8
-; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp slt i8 [[TRUNC2]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[TOBOOL]], [[TOBOOL3]]
-; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[OR_COND]], i32 2, i32 1
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 1, i32 2
; CHECK-NEXT: ret i32 [[RETVAL_0]]
;
%and = and i32 %argc, 64
@@ -539,12 +536,9 @@ define i32 @main8(i32 %argc) {
define i32 @main9(i32 %argc) {
; CHECK-LABEL: @main9(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[ARGC:%.*]], 64
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 0
-; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i32 [[ARGC]] to i8
-; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp slt i8 [[TRUNC2]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[TOBOOL]], [[TOBOOL3]]
-; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[OR_COND]], i32 2, i32 1
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 192
+; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 2, i32 1
; CHECK-NEXT: ret i32 [[RETVAL_0]]
;
%and = and i32 %argc, 64
@@ -558,12 +552,9 @@ define i32 @main9(i32 %argc) {
define i32 @main10(i32 %argc) {
; CHECK-LABEL: @main10(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[ARGC:%.*]], 64
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0
-; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i32 [[ARGC]] to i8
-; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp sgt i8 [[TRUNC2]], -1
-; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[TOBOOL]], [[TOBOOL3]]
-; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[OR_COND]], i32 2, i32 1
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 2, i32 1
; CHECK-NEXT: ret i32 [[RETVAL_0]]
;
%and = and i32 %argc, 64
@@ -577,12 +568,9 @@ define i32 @main10(i32 %argc) {
define i32 @main11(i32 %argc) {
; CHECK-LABEL: @main11(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[ARGC:%.*]], 64
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0
-; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i32 [[ARGC]] to i8
-; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp sgt i8 [[TRUNC2]], -1
-; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[TOBOOL]], [[TOBOOL3]]
-; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[OR_COND]], i32 2, i32 1
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 192
+; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 1, i32 2
; CHECK-NEXT: ret i32 [[RETVAL_0]]
;
%and = and i32 %argc, 64
@@ -596,12 +584,9 @@ define i32 @main11(i32 %argc) {
define i32 @main12(i32 %argc) {
; CHECK-LABEL: @main12(
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[ARGC:%.*]] to i16
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i16 [[TRUNC]], 0
-; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i32 [[ARGC]] to i8
-; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp slt i8 [[TRUNC2]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[TOBOOL]], [[TOBOOL3]]
-; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[OR_COND]], i32 2, i32 1
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 1, i32 2
; CHECK-NEXT: ret i32 [[RETVAL_0]]
;
%trunc = trunc i32 %argc to i16
@@ -615,12 +600,9 @@ define i32 @main12(i32 %argc) {
define i32 @main13(i32 %argc) {
; CHECK-LABEL: @main13(
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[ARGC:%.*]] to i16
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i16 [[TRUNC]], 0
-; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i32 [[ARGC]] to i8
-; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp slt i8 [[TRUNC2]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[TOBOOL]], [[TOBOOL3]]
-; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[OR_COND]], i32 2, i32 1
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 32896
+; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 2, i32 1
; CHECK-NEXT: ret i32 [[RETVAL_0]]
;
%trunc = trunc i32 %argc to i16
@@ -634,12 +616,9 @@ define i32 @main13(i32 %argc) {
define i32 @main14(i32 %argc) {
; CHECK-LABEL: @main14(
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[ARGC:%.*]] to i16
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp sgt i16 [[TRUNC]], -1
-; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i32 [[ARGC]] to i8
-; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp sgt i8 [[TRUNC2]], -1
-; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[TOBOOL]], [[TOBOOL3]]
-; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[OR_COND]], i32 2, i32 1
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 2, i32 1
; CHECK-NEXT: ret i32 [[RETVAL_0]]
;
%trunc = trunc i32 %argc to i16
@@ -653,12 +632,9 @@ define i32 @main14(i32 %argc) {
define i32 @main15(i32 %argc) {
; CHECK-LABEL: @main15(
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[ARGC:%.*]] to i16
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp sgt i16 [[TRUNC]], -1
-; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i32 [[ARGC]] to i8
-; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp sgt i8 [[TRUNC2]], -1
-; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[TOBOOL]], [[TOBOOL3]]
-; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[OR_COND]], i32 2, i32 1
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 32896
+; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 1, i32 2
; CHECK-NEXT: ret i32 [[RETVAL_0]]
;
%trunc = trunc i32 %argc to i16
OpenPOWER on IntegriCloud