mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[SCEV] Fix for PR42397. SCEVExpander wrongly adds nsw to shl instruction.
Change-Id: I76c9f628c092ae3e6e78ebdaf55cec726e25d692 llvm-svn: 365363
This commit is contained in:
parent
e52525bbb5
commit
bdc34231f3
@ -838,9 +838,13 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) {
|
||||
if (match(W, m_Power2(RHS))) {
|
||||
// Canonicalize Prod*(1<<C) to Prod<<C.
|
||||
assert(!Ty->isVectorTy() && "vector types are not SCEVable");
|
||||
auto NWFlags = S->getNoWrapFlags();
|
||||
// clear nsw flag if shl will produce poison value.
|
||||
if (RHS->logBase2() == RHS->getBitWidth() - 1)
|
||||
NWFlags = ScalarEvolution::clearFlags(NWFlags, SCEV::FlagNSW);
|
||||
Prod = InsertBinop(Instruction::Shl, Prod,
|
||||
ConstantInt::get(Ty, RHS->logBase2()),
|
||||
S->getNoWrapFlags(), /*IsSafeToHoist*/ true);
|
||||
ConstantInt::get(Ty, RHS->logBase2()), NWFlags,
|
||||
/*IsSafeToHoist*/ true);
|
||||
} else {
|
||||
Prod = InsertBinop(Instruction::Mul, Prod, W, S->getNoWrapFlags(),
|
||||
/*IsSafeToHoist*/ true);
|
||||
|
@ -1637,5 +1637,46 @@ TEST_F(ScalarEvolutionsTest, SCEVExpandInsertCanonicalIV) {
|
||||
TestMatchingCanonicalIV(GetAR2, ARBitWidth);
|
||||
}
|
||||
|
||||
TEST_F(ScalarEvolutionsTest, SCEVExpanderShlNSW) {
|
||||
|
||||
auto checkOneCase = [this](std::string &&str) {
|
||||
LLVMContext C;
|
||||
SMDiagnostic Err;
|
||||
std::unique_ptr<Module> M = parseAssemblyString(str, Err, C);
|
||||
|
||||
assert(M && "Could not parse module?");
|
||||
assert(!verifyModule(*M) && "Must have been well formed!");
|
||||
|
||||
Function *F = M->getFunction("f");
|
||||
ASSERT_NE(F, nullptr) << "Could not find function 'f'";
|
||||
|
||||
BasicBlock &Entry = F->getEntryBlock();
|
||||
LoadInst *Load = cast<LoadInst>(&Entry.front());
|
||||
BinaryOperator *And = cast<BinaryOperator>(*Load->user_begin());
|
||||
|
||||
ScalarEvolution SE = buildSE(*F);
|
||||
const SCEV *AndSCEV = SE.getSCEV(And);
|
||||
EXPECT_TRUE(isa<SCEVMulExpr>(AndSCEV));
|
||||
EXPECT_TRUE(cast<SCEVMulExpr>(AndSCEV)->hasNoSignedWrap());
|
||||
|
||||
SCEVExpander Exp(SE, M->getDataLayout(), "expander");
|
||||
auto *I = cast<Instruction>(Exp.expandCodeFor(AndSCEV, nullptr, And));
|
||||
EXPECT_EQ(I->getOpcode(), Instruction::Shl);
|
||||
EXPECT_FALSE(I->hasNoSignedWrap());
|
||||
};
|
||||
|
||||
checkOneCase("define void @f(i16* %arrayidx) { "
|
||||
" %1 = load i16, i16* %arrayidx "
|
||||
" %2 = and i16 %1, -32768 "
|
||||
" ret void "
|
||||
"} ");
|
||||
|
||||
checkOneCase("define void @f(i8* %arrayidx) { "
|
||||
" %1 = load i8, i8* %arrayidx "
|
||||
" %2 = and i8 %1, -128 "
|
||||
" ret void "
|
||||
"} ");
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
} // end namespace llvm
|
||||
|
Loading…
Reference in New Issue
Block a user