mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-27 15:22:29 +00:00
[InstCombine] use m_APInt to allow icmp eq (op X, Y), C folds for splat constant vectors
I'm removing a misplaced pair of more specific folds from InstCombine in this patch as well, so we know where those folds are happening in InstSimplify. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277738 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dbed1dc732
commit
47b6d6791b
@ -3121,17 +3121,16 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
|||||||
// If a bit is known to be zero for A and known to be one for B,
|
// If a bit is known to be zero for A and known to be one for B,
|
||||||
// then A and B cannot be equal.
|
// then A and B cannot be equal.
|
||||||
if (ICmpInst::isEquality(Pred)) {
|
if (ICmpInst::isEquality(Pred)) {
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
|
const APInt *RHSVal;
|
||||||
uint32_t BitWidth = CI->getBitWidth();
|
if (match(RHS, m_APInt(RHSVal))) {
|
||||||
|
unsigned BitWidth = RHSVal->getBitWidth();
|
||||||
APInt LHSKnownZero(BitWidth, 0);
|
APInt LHSKnownZero(BitWidth, 0);
|
||||||
APInt LHSKnownOne(BitWidth, 0);
|
APInt LHSKnownOne(BitWidth, 0);
|
||||||
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, Q.DL, /*Depth=*/0, Q.AC,
|
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, Q.DL, /*Depth=*/0, Q.AC,
|
||||||
Q.CxtI, Q.DT);
|
Q.CxtI, Q.DT);
|
||||||
const APInt &RHSVal = CI->getValue();
|
if (((LHSKnownZero & *RHSVal) != 0) || ((LHSKnownOne & ~(*RHSVal)) != 0))
|
||||||
if (((LHSKnownZero & RHSVal) != 0) || ((LHSKnownOne & ~RHSVal) != 0))
|
return Pred == ICmpInst::ICMP_EQ ? ConstantInt::getFalse(ITy)
|
||||||
return Pred == ICmpInst::ICMP_EQ
|
: ConstantInt::getTrue(ITy);
|
||||||
? ConstantInt::getFalse(CI->getContext())
|
|
||||||
: ConstantInt::getTrue(CI->getContext());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2277,14 +2277,8 @@ Instruction *InstCombiner::foldICmpEqualityWithConstant(ICmpInst &ICI) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Instruction::Or:
|
case Instruction::Or:
|
||||||
// If bits are being or'd in that are not present in the constant we
|
|
||||||
// are comparing against, then the comparison could never succeed!
|
|
||||||
// FIXME: Vectors are excluded by ConstantInt.
|
// FIXME: Vectors are excluded by ConstantInt.
|
||||||
if (ConstantInt *BOC = dyn_cast<ConstantInt>(BOp1)) {
|
if (ConstantInt *BOC = dyn_cast<ConstantInt>(BOp1)) {
|
||||||
Constant *NotCI = ConstantExpr::getNot(RHS);
|
|
||||||
if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue())
|
|
||||||
return replaceInstUsesWith(ICI, Builder->getInt1(isICMP_NE));
|
|
||||||
|
|
||||||
// Comparing if all bits outside of a constant mask are set?
|
// Comparing if all bits outside of a constant mask are set?
|
||||||
// Replace (X | C) == -1 with (X & ~C) == ~C.
|
// Replace (X | C) == -1 with (X & ~C) == ~C.
|
||||||
// This removes the -1 constant.
|
// This removes the -1 constant.
|
||||||
@ -2299,11 +2293,6 @@ Instruction *InstCombiner::foldICmpEqualityWithConstant(ICmpInst &ICI) {
|
|||||||
case Instruction::And:
|
case Instruction::And:
|
||||||
// FIXME: Vectors are excluded by ConstantInt.
|
// FIXME: Vectors are excluded by ConstantInt.
|
||||||
if (ConstantInt *BOC = dyn_cast<ConstantInt>(BOp1)) {
|
if (ConstantInt *BOC = dyn_cast<ConstantInt>(BOp1)) {
|
||||||
// If bits are being compared against that are and'd out, then the
|
|
||||||
// comparison can never succeed!
|
|
||||||
if ((*RHSV & ~BOC->getValue()) != 0)
|
|
||||||
return replaceInstUsesWith(ICI, Builder->getInt1(isICMP_NE));
|
|
||||||
|
|
||||||
// If we have ((X & C) == C), turn it into ((X & C) != 0).
|
// If we have ((X & C) == C), turn it into ((X & C) != 0).
|
||||||
if (RHS == BOC && RHSV->isPowerOf2())
|
if (RHS == BOC && RHSV->isPowerOf2())
|
||||||
return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE,
|
return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
; RUN: opt < %s -instsimplify -S | FileCheck %s
|
; RUN: opt < %s -instsimplify -S | FileCheck %s
|
||||||
target datalayout = "p:32:32"
|
target datalayout = "p:32:32"
|
||||||
|
|
||||||
@ -1017,9 +1018,7 @@ define i1 @icmp_eq_const(i32 %a) {
|
|||||||
; FIXME: Vectors should fold the same way.
|
; FIXME: Vectors should fold the same way.
|
||||||
define <2 x i1> @icmp_eq_const_vec(<2 x i32> %a) {
|
define <2 x i1> @icmp_eq_const_vec(<2 x i32> %a) {
|
||||||
; CHECK-LABEL: @icmp_eq_const_vec(
|
; CHECK-LABEL: @icmp_eq_const_vec(
|
||||||
; CHECK-NEXT: [[B:%.*]] = mul nsw <2 x i32> %a, <i32 -2, i32 -2>
|
; CHECK-NEXT: ret <2 x i1> zeroinitializer
|
||||||
; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[B]], <i32 1, i32 1>
|
|
||||||
; CHECK-NEXT: ret <2 x i1> [[C]]
|
|
||||||
;
|
;
|
||||||
%b = mul nsw <2 x i32> %a, <i32 -2, i32 -2>
|
%b = mul nsw <2 x i32> %a, <i32 -2, i32 -2>
|
||||||
%c = icmp eq <2 x i32> %b, <i32 1, i32 1>
|
%c = icmp eq <2 x i32> %b, <i32 1, i32 1>
|
||||||
@ -1038,9 +1037,7 @@ define i1 @icmp_ne_const(i32 %a) {
|
|||||||
; FIXME: Vectors should fold the same way.
|
; FIXME: Vectors should fold the same way.
|
||||||
define <2 x i1> @icmp_ne_const_vec(<2 x i32> %a) {
|
define <2 x i1> @icmp_ne_const_vec(<2 x i32> %a) {
|
||||||
; CHECK-LABEL: @icmp_ne_const_vec(
|
; CHECK-LABEL: @icmp_ne_const_vec(
|
||||||
; CHECK-NEXT: [[B:%.*]] = mul nsw <2 x i32> %a, <i32 -2, i32 -2>
|
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
|
||||||
; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[B]], <i32 1, i32 1>
|
|
||||||
; CHECK-NEXT: ret <2 x i1> [[C]]
|
|
||||||
;
|
;
|
||||||
%b = mul nsw <2 x i32> %a, <i32 -2, i32 -2>
|
%b = mul nsw <2 x i32> %a, <i32 -2, i32 -2>
|
||||||
%c = icmp ne <2 x i32> %b, <i32 1, i32 1>
|
%c = icmp ne <2 x i32> %b, <i32 1, i32 1>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user