[llvm] r365363 - [SCEV] Fix for PR42397. SCEVExpander wrongly adds nsw to shl instruction.
Denis Bakhvalov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 8 11:03:43 PDT 2019
Author: dendibakh
Date: Mon Jul 8 11:03:43 2019
New Revision: 365363
URL: http://llvm.org/viewvc/llvm-project?rev=365363&view=rev
Log:
[SCEV] Fix for PR42397. SCEVExpander wrongly adds nsw to shl instruction.
Change-Id: I76c9f628c092ae3e6e78ebdaf55cec726e25d692
Modified:
llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
llvm/trunk/unittests/Analysis/ScalarEvolutionTest.cpp
Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=365363&r1=365362&r2=365363&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Mon Jul 8 11:03:43 2019
@@ -838,9 +838,13 @@ Value *SCEVExpander::visitMulExpr(const
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);
Modified: llvm/trunk/unittests/Analysis/ScalarEvolutionTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/ScalarEvolutionTest.cpp?rev=365363&r1=365362&r2=365363&view=diff
==============================================================================
--- llvm/trunk/unittests/Analysis/ScalarEvolutionTest.cpp (original)
+++ llvm/trunk/unittests/Analysis/ScalarEvolutionTest.cpp Mon Jul 8 11:03:43 2019
@@ -1637,5 +1637,46 @@ TEST_F(ScalarEvolutionsTest, SCEVExpandI
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
More information about the llvm-commits
mailing list