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,9 +1846,10 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
|
||||
if (const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS)) {
|
||||
if (RHSC->getValue()->equalsInt(1))
|
||||
return LHS; // X udiv 1 --> x
|
||||
if (RHSC->getValue()->isZero())
|
||||
return getIntegerSCEV(0, LHS->getType()); // value is undefined
|
||||
|
||||
// If the denominator is zero, the result of the udiv 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 (!RHSC->getValue()->isZero()) {
|
||||
// Determine if the division can be folded into the operands of
|
||||
// its operands.
|
||||
// TODO: Generalize this to non-constants by using known-bits information.
|
||||
@ -1887,7 +1888,8 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
|
||||
const SCEV *Op = M->getOperand(i);
|
||||
const SCEV *Div = getUDivExpr(Op, RHSC);
|
||||
if (!isa<SCEVUDivExpr>(Div) && getMulExpr(Div, RHSC) == Op) {
|
||||
Operands = SmallVector<const SCEV *, 4>(M->op_begin(), M->op_end());
|
||||
Operands = SmallVector<const SCEV *, 4>(M->op_begin(),
|
||||
M->op_end());
|
||||
Operands[i] = Div;
|
||||
return getMulExpr(Operands);
|
||||
}
|
||||
@ -1902,7 +1904,8 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
|
||||
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))
|
||||
if (isa<SCEVUDivExpr>(Op) ||
|
||||
getMulExpr(Op, RHS) != A->getOperand(i))
|
||||
break;
|
||||
Operands.push_back(Op);
|
||||
}
|
||||
@ -1919,6 +1922,7 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
|
||||
RHSCV)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scUDivExpr);
|
||||
@ -3319,8 +3323,16 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
|
||||
// Turn shift left of a constant amount into a multiply.
|
||||
if (ConstantInt *SA = dyn_cast<ConstantInt>(U->getOperand(1))) {
|
||||
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(),
|
||||
APInt(BitWidth, 1).shl(SA->getLimitedValue(BitWidth)));
|
||||
APInt(BitWidth, 1).shl(SA->getZExtValue()));
|
||||
return getMulExpr(getSCEV(U->getOperand(0)), getSCEV(X));
|
||||
}
|
||||
break;
|
||||
@ -3329,8 +3341,16 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
|
||||
// Turn logical shift right of a constant into a unsigned divide.
|
||||
if (ConstantInt *SA = dyn_cast<ConstantInt>(U->getOperand(1))) {
|
||||
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(),
|
||||
APInt(BitWidth, 1).shl(SA->getLimitedValue(BitWidth)));
|
||||
APInt(BitWidth, 1).shl(SA->getZExtValue()));
|
||||
return getUDivExpr(getSCEV(U->getOperand(0)), getSCEV(X));
|
||||
}
|
||||
break;
|
||||
@ -3338,18 +3358,25 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
|
||||
case Instruction::AShr:
|
||||
// For a two-shift sext-inreg, use sext(trunc(x)) as the SCEV expression.
|
||||
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 &&
|
||||
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();
|
||||
if (Amt == BitWidth)
|
||||
return getSCEV(L->getOperand(0)); // shift by zero --> noop
|
||||
if (Amt > BitWidth)
|
||||
return getIntegerSCEV(0, U->getType()); // value is undefined
|
||||
return
|
||||
getSignExtendExpr(getTruncateExpr(getSCEV(L->getOperand(0)),
|
||||
IntegerType::get(getContext(), Amt)),
|
||||
IntegerType::get(getContext(),
|
||||
Amt)),
|
||||
U->getType());
|
||||
}
|
||||
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