mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Don't attempt to analyze values which are obviously undef. This fixes some
assertion failures in extreme cases. llvm-svn: 102042
This commit is contained in:
parent
1af81d31e9
commit
31d6b29bae
@ -1846,77 +1846,81 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
|
|||||||
if (const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS)) {
|
if (const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS)) {
|
||||||
if (RHSC->getValue()->equalsInt(1))
|
if (RHSC->getValue()->equalsInt(1))
|
||||||
return LHS; // X udiv 1 --> x
|
return LHS; // X udiv 1 --> x
|
||||||
if (RHSC->getValue()->isZero())
|
// If the denominator is zero, the result of the udiv is undefined. Don't
|
||||||
return getIntegerSCEV(0, LHS->getType()); // value is undefined
|
// try to analyze it, because the resolution chosen here may differ from
|
||||||
|
// the resolution chosen in other parts of the compiler.
|
||||||
// Determine if the division can be folded into the operands of
|
if (!RHSC->getValue()->isZero()) {
|
||||||
// its operands.
|
// Determine if the division can be folded into the operands of
|
||||||
// TODO: Generalize this to non-constants by using known-bits information.
|
// its operands.
|
||||||
const Type *Ty = LHS->getType();
|
// TODO: Generalize this to non-constants by using known-bits information.
|
||||||
unsigned LZ = RHSC->getValue()->getValue().countLeadingZeros();
|
const Type *Ty = LHS->getType();
|
||||||
unsigned MaxShiftAmt = getTypeSizeInBits(Ty) - LZ;
|
unsigned LZ = RHSC->getValue()->getValue().countLeadingZeros();
|
||||||
// For non-power-of-two values, effectively round the value up to the
|
unsigned MaxShiftAmt = getTypeSizeInBits(Ty) - LZ;
|
||||||
// nearest power of two.
|
// For non-power-of-two values, effectively round the value up to the
|
||||||
if (!RHSC->getValue()->getValue().isPowerOf2())
|
// nearest power of two.
|
||||||
++MaxShiftAmt;
|
if (!RHSC->getValue()->getValue().isPowerOf2())
|
||||||
const IntegerType *ExtTy =
|
++MaxShiftAmt;
|
||||||
IntegerType::get(getContext(), getTypeSizeInBits(Ty) + MaxShiftAmt);
|
const IntegerType *ExtTy =
|
||||||
// {X,+,N}/C --> {X/C,+,N/C} if safe and N/C can be folded.
|
IntegerType::get(getContext(), getTypeSizeInBits(Ty) + MaxShiftAmt);
|
||||||
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(LHS))
|
// {X,+,N}/C --> {X/C,+,N/C} if safe and N/C can be folded.
|
||||||
if (const SCEVConstant *Step =
|
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(LHS))
|
||||||
dyn_cast<SCEVConstant>(AR->getStepRecurrence(*this)))
|
if (const SCEVConstant *Step =
|
||||||
if (!Step->getValue()->getValue()
|
dyn_cast<SCEVConstant>(AR->getStepRecurrence(*this)))
|
||||||
.urem(RHSC->getValue()->getValue()) &&
|
if (!Step->getValue()->getValue()
|
||||||
getZeroExtendExpr(AR, ExtTy) ==
|
.urem(RHSC->getValue()->getValue()) &&
|
||||||
getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy),
|
getZeroExtendExpr(AR, ExtTy) ==
|
||||||
getZeroExtendExpr(Step, ExtTy),
|
getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy),
|
||||||
AR->getLoop())) {
|
getZeroExtendExpr(Step, ExtTy),
|
||||||
SmallVector<const SCEV *, 4> Operands;
|
AR->getLoop())) {
|
||||||
for (unsigned i = 0, e = AR->getNumOperands(); i != e; ++i)
|
SmallVector<const SCEV *, 4> Operands;
|
||||||
Operands.push_back(getUDivExpr(AR->getOperand(i), RHS));
|
for (unsigned i = 0, e = AR->getNumOperands(); i != e; ++i)
|
||||||
return getAddRecExpr(Operands, AR->getLoop());
|
Operands.push_back(getUDivExpr(AR->getOperand(i), RHS));
|
||||||
}
|
return getAddRecExpr(Operands, AR->getLoop());
|
||||||
// (A*B)/C --> A*(B/C) if safe and B/C can be folded.
|
}
|
||||||
if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(LHS)) {
|
// (A*B)/C --> A*(B/C) if safe and B/C can be folded.
|
||||||
SmallVector<const SCEV *, 4> Operands;
|
if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(LHS)) {
|
||||||
for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i)
|
SmallVector<const SCEV *, 4> Operands;
|
||||||
Operands.push_back(getZeroExtendExpr(M->getOperand(i), ExtTy));
|
for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i)
|
||||||
if (getZeroExtendExpr(M, ExtTy) == getMulExpr(Operands))
|
Operands.push_back(getZeroExtendExpr(M->getOperand(i), ExtTy));
|
||||||
// Find an operand that's safely divisible.
|
if (getZeroExtendExpr(M, ExtTy) == getMulExpr(Operands))
|
||||||
for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i) {
|
// Find an operand that's safely divisible.
|
||||||
const SCEV *Op = M->getOperand(i);
|
for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i) {
|
||||||
const SCEV *Div = getUDivExpr(Op, RHSC);
|
const SCEV *Op = M->getOperand(i);
|
||||||
if (!isa<SCEVUDivExpr>(Div) && getMulExpr(Div, RHSC) == Op) {
|
const SCEV *Div = getUDivExpr(Op, RHSC);
|
||||||
Operands = SmallVector<const SCEV *, 4>(M->op_begin(), M->op_end());
|
if (!isa<SCEVUDivExpr>(Div) && getMulExpr(Div, RHSC) == Op) {
|
||||||
Operands[i] = Div;
|
Operands = SmallVector<const SCEV *, 4>(M->op_begin(),
|
||||||
return getMulExpr(Operands);
|
M->op_end());
|
||||||
|
Operands[i] = Div;
|
||||||
|
return getMulExpr(Operands);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
// (A+B)/C --> (A/C + B/C) if safe and A/C and B/C can be folded.
|
|
||||||
if (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(LHS)) {
|
|
||||||
SmallVector<const SCEV *, 4> Operands;
|
|
||||||
for (unsigned i = 0, e = A->getNumOperands(); i != e; ++i)
|
|
||||||
Operands.push_back(getZeroExtendExpr(A->getOperand(i), ExtTy));
|
|
||||||
if (getZeroExtendExpr(A, ExtTy) == getAddExpr(Operands)) {
|
|
||||||
Operands.clear();
|
|
||||||
for (unsigned i = 0, e = A->getNumOperands(); i != e; ++i) {
|
|
||||||
const SCEV *Op = getUDivExpr(A->getOperand(i), RHS);
|
|
||||||
if (isa<SCEVUDivExpr>(Op) || getMulExpr(Op, RHS) != A->getOperand(i))
|
|
||||||
break;
|
|
||||||
Operands.push_back(Op);
|
|
||||||
}
|
|
||||||
if (Operands.size() == A->getNumOperands())
|
|
||||||
return getAddExpr(Operands);
|
|
||||||
}
|
}
|
||||||
}
|
// (A+B)/C --> (A/C + B/C) if safe and A/C and B/C can be folded.
|
||||||
|
if (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(LHS)) {
|
||||||
|
SmallVector<const SCEV *, 4> Operands;
|
||||||
|
for (unsigned i = 0, e = A->getNumOperands(); i != e; ++i)
|
||||||
|
Operands.push_back(getZeroExtendExpr(A->getOperand(i), ExtTy));
|
||||||
|
if (getZeroExtendExpr(A, ExtTy) == getAddExpr(Operands)) {
|
||||||
|
Operands.clear();
|
||||||
|
for (unsigned i = 0, e = A->getNumOperands(); i != e; ++i) {
|
||||||
|
const SCEV *Op = getUDivExpr(A->getOperand(i), RHS);
|
||||||
|
if (isa<SCEVUDivExpr>(Op) ||
|
||||||
|
getMulExpr(Op, RHS) != A->getOperand(i))
|
||||||
|
break;
|
||||||
|
Operands.push_back(Op);
|
||||||
|
}
|
||||||
|
if (Operands.size() == A->getNumOperands())
|
||||||
|
return getAddExpr(Operands);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fold if both operands are constant.
|
// Fold if both operands are constant.
|
||||||
if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS)) {
|
if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS)) {
|
||||||
Constant *LHSCV = LHSC->getValue();
|
Constant *LHSCV = LHSC->getValue();
|
||||||
Constant *RHSCV = RHSC->getValue();
|
Constant *RHSCV = RHSC->getValue();
|
||||||
return getConstant(cast<ConstantInt>(ConstantExpr::getUDiv(LHSCV,
|
return getConstant(cast<ConstantInt>(ConstantExpr::getUDiv(LHSCV,
|
||||||
RHSCV)));
|
RHSCV)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3319,8 +3323,16 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
|
|||||||
// Turn shift left of a constant amount into a multiply.
|
// Turn shift left of a constant amount into a multiply.
|
||||||
if (ConstantInt *SA = dyn_cast<ConstantInt>(U->getOperand(1))) {
|
if (ConstantInt *SA = dyn_cast<ConstantInt>(U->getOperand(1))) {
|
||||||
uint32_t BitWidth = cast<IntegerType>(U->getType())->getBitWidth();
|
uint32_t BitWidth = cast<IntegerType>(U->getType())->getBitWidth();
|
||||||
|
|
||||||
|
// If the shift count is not less than the bitwidth, the result of
|
||||||
|
// the shift is undefined. Don't try to analyze it, because the
|
||||||
|
// resolution chosen here may differ from the resolution chosen in
|
||||||
|
// other parts of the compiler.
|
||||||
|
if (SA->getValue().uge(BitWidth))
|
||||||
|
break;
|
||||||
|
|
||||||
Constant *X = ConstantInt::get(getContext(),
|
Constant *X = ConstantInt::get(getContext(),
|
||||||
APInt(BitWidth, 1).shl(SA->getLimitedValue(BitWidth)));
|
APInt(BitWidth, 1).shl(SA->getZExtValue()));
|
||||||
return getMulExpr(getSCEV(U->getOperand(0)), getSCEV(X));
|
return getMulExpr(getSCEV(U->getOperand(0)), getSCEV(X));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3329,8 +3341,16 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
|
|||||||
// Turn logical shift right of a constant into a unsigned divide.
|
// Turn logical shift right of a constant into a unsigned divide.
|
||||||
if (ConstantInt *SA = dyn_cast<ConstantInt>(U->getOperand(1))) {
|
if (ConstantInt *SA = dyn_cast<ConstantInt>(U->getOperand(1))) {
|
||||||
uint32_t BitWidth = cast<IntegerType>(U->getType())->getBitWidth();
|
uint32_t BitWidth = cast<IntegerType>(U->getType())->getBitWidth();
|
||||||
|
|
||||||
|
// If the shift count is not less than the bitwidth, the result of
|
||||||
|
// the shift is undefined. Don't try to analyze it, because the
|
||||||
|
// resolution chosen here may differ from the resolution chosen in
|
||||||
|
// other parts of the compiler.
|
||||||
|
if (SA->getValue().uge(BitWidth))
|
||||||
|
break;
|
||||||
|
|
||||||
Constant *X = ConstantInt::get(getContext(),
|
Constant *X = ConstantInt::get(getContext(),
|
||||||
APInt(BitWidth, 1).shl(SA->getLimitedValue(BitWidth)));
|
APInt(BitWidth, 1).shl(SA->getZExtValue()));
|
||||||
return getUDivExpr(getSCEV(U->getOperand(0)), getSCEV(X));
|
return getUDivExpr(getSCEV(U->getOperand(0)), getSCEV(X));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3338,19 +3358,26 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
|
|||||||
case Instruction::AShr:
|
case Instruction::AShr:
|
||||||
// For a two-shift sext-inreg, use sext(trunc(x)) as the SCEV expression.
|
// For a two-shift sext-inreg, use sext(trunc(x)) as the SCEV expression.
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(U->getOperand(1)))
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(U->getOperand(1)))
|
||||||
if (Instruction *L = dyn_cast<Instruction>(U->getOperand(0)))
|
if (Operator *L = dyn_cast<Operator>(U->getOperand(0)))
|
||||||
if (L->getOpcode() == Instruction::Shl &&
|
if (L->getOpcode() == Instruction::Shl &&
|
||||||
L->getOperand(1) == U->getOperand(1)) {
|
L->getOperand(1) == U->getOperand(1)) {
|
||||||
unsigned BitWidth = getTypeSizeInBits(U->getType());
|
uint64_t BitWidth = getTypeSizeInBits(U->getType());
|
||||||
|
|
||||||
|
// If the shift count is not less than the bitwidth, the result of
|
||||||
|
// the shift is undefined. Don't try to analyze it, because the
|
||||||
|
// resolution chosen here may differ from the resolution chosen in
|
||||||
|
// other parts of the compiler.
|
||||||
|
if (CI->getValue().uge(BitWidth))
|
||||||
|
break;
|
||||||
|
|
||||||
uint64_t Amt = BitWidth - CI->getZExtValue();
|
uint64_t Amt = BitWidth - CI->getZExtValue();
|
||||||
if (Amt == BitWidth)
|
if (Amt == BitWidth)
|
||||||
return getSCEV(L->getOperand(0)); // shift by zero --> noop
|
return getSCEV(L->getOperand(0)); // shift by zero --> noop
|
||||||
if (Amt > BitWidth)
|
|
||||||
return getIntegerSCEV(0, U->getType()); // value is undefined
|
|
||||||
return
|
return
|
||||||
getSignExtendExpr(getTruncateExpr(getSCEV(L->getOperand(0)),
|
getSignExtendExpr(getTruncateExpr(getSCEV(L->getOperand(0)),
|
||||||
IntegerType::get(getContext(), Amt)),
|
IntegerType::get(getContext(),
|
||||||
U->getType());
|
Amt)),
|
||||||
|
U->getType());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
39
test/Analysis/ScalarEvolution/undefined.ll
Normal file
39
test/Analysis/ScalarEvolution/undefined.ll
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
|
||||||
|
|
||||||
|
; ScalarEvolution shouldn't attempt to interpret expressions which have
|
||||||
|
; undefined results.
|
||||||
|
|
||||||
|
define void @foo(i64 %x) {
|
||||||
|
|
||||||
|
%a = udiv i64 %x, 0
|
||||||
|
; CHECK: --> (%x /u 0)
|
||||||
|
|
||||||
|
%B = shl i64 %x, 64
|
||||||
|
; CHECK: --> %B
|
||||||
|
|
||||||
|
%b = ashr i64 %B, 64
|
||||||
|
; CHECK: --> %b
|
||||||
|
|
||||||
|
%c = lshr i64 %x, 64
|
||||||
|
; CHECK: --> %c
|
||||||
|
|
||||||
|
%d = shl i64 %x, 64
|
||||||
|
; CHECK: --> %d
|
||||||
|
|
||||||
|
%E = shl i64 %x, -1
|
||||||
|
; CHECK: --> %E
|
||||||
|
|
||||||
|
%e = ashr i64 %E, -1
|
||||||
|
; CHECK: --> %e
|
||||||
|
|
||||||
|
%f = lshr i64 %x, -1
|
||||||
|
; CHECK: --> %f
|
||||||
|
|
||||||
|
%g = shl i64 %x, -1
|
||||||
|
; CHECK: --> %g
|
||||||
|
|
||||||
|
%h = bitcast i64 undef to i64
|
||||||
|
; CHECK: --> undef
|
||||||
|
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user