1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02:00

[InstCombine] use m_APInt to allow icmp (sub X, Y), C folds for splat constant vectors

llvm-svn: 278859
This commit is contained in:
Sanjay Patel 2016-08-16 21:53:19 +00:00
parent 312f8e2915
commit 110b6da1b2
2 changed files with 14 additions and 21 deletions

View File

@ -2170,32 +2170,27 @@ Instruction *InstCombiner::foldICmpDivConstant(ICmpInst &ICI, Instruction *LHSI,
/// Fold icmp (sub X, Y), C.
Instruction *InstCombiner::foldICmpSubConstant(ICmpInst &Cmp, Instruction *Sub,
const APInt *C) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(Cmp.getOperand(1));
if (!RHS)
const APInt *C2;
if (!match(Sub->getOperand(0), m_APInt(C2)) || !Sub->hasOneUse())
return nullptr;
ConstantInt *SubC = dyn_cast<ConstantInt>(Sub->getOperand(0));
if (!SubC)
return nullptr;
const APInt &C2 = SubC->getValue();
// C-X <u C2 -> (X|(C2-1)) == C
// iff C & (C2-1) == C2-1
// C2 is a power of 2
if (Cmp.getPredicate() == ICmpInst::ICMP_ULT && Sub->hasOneUse() &&
C->isPowerOf2() && (C2 & (*C - 1)) == (*C - 1))
if (Cmp.getPredicate() == ICmpInst::ICMP_ULT && C->isPowerOf2() &&
(*C2 & (*C - 1)) == (*C - 1))
return new ICmpInst(ICmpInst::ICMP_EQ,
Builder->CreateOr(Sub->getOperand(1), *C - 1), SubC);
Builder->CreateOr(Sub->getOperand(1), *C - 1),
Sub->getOperand(0));
// C-X >u C2 -> (X|C2) != C
// iff C & C2 == C2
// C2+1 is a power of 2
if (Cmp.getPredicate() == ICmpInst::ICMP_UGT && Sub->hasOneUse() &&
(*C + 1).isPowerOf2() && (C2 & *C) == *C)
if (Cmp.getPredicate() == ICmpInst::ICMP_UGT && (*C + 1).isPowerOf2() &&
(*C2 & *C) == *C)
return new ICmpInst(ICmpInst::ICMP_NE,
Builder->CreateOr(Sub->getOperand(1), *C), SubC);
Builder->CreateOr(Sub->getOperand(1), *C),
Sub->getOperand(0));
return nullptr;
}

View File

@ -1750,11 +1750,10 @@ define i1 @icmp_sub_3_X_ult_2(i32 %X) {
ret i1 %cmp
}
; FIXME: Vectors should fold too.
define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) {
; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec(
; CHECK-NEXT: [[ADD:%.*]] = sub <2 x i32> <i32 3, i32 3>, %X
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[ADD]], <i32 2, i32 2>
; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> %X, <i32 1, i32 1>
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 3, i32 3>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%add = sub <2 x i32> <i32 3, i32 3>, %X
@ -1796,11 +1795,10 @@ define i1 @icmp_sub_3_X_uge_2(i32 %X) {
ret i1 %cmp
}
; FIXME: Vectors should fold too.
define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) {
; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec(
; CHECK-NEXT: [[ADD:%.*]] = sub <2 x i32> <i32 3, i32 3>, %X
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[ADD]], <i32 1, i32 1>
; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> %X, <i32 1, i32 1>
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 3, i32 3>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%add = sub <2 x i32> <i32 3, i32 3>, %X