llvm.org GIT mirror llvm / 21e1c39
[SCEV] Fix for PR42397. SCEVExpander wrongly adds nsw to shl instruction. Change-Id: I76c9f628c092ae3e6e78ebdaf55cec726e25d692 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365363 91177308-0d34-0410-b5e6-96231b3b80d8 Denis Bakhvalov a month ago
2 changed file(s) with 47 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
837837 if (match(W, m_Power2(RHS))) {
838838 // Canonicalize Prod*(1<
839839 assert(!Ty->isVectorTy() && "vector types are not SCEVable");
840 auto NWFlags = S->getNoWrapFlags();
841 // clear nsw flag if shl will produce poison value.
842 if (RHS->logBase2() == RHS->getBitWidth() - 1)
843 NWFlags = ScalarEvolution::clearFlags(NWFlags, SCEV::FlagNSW);
840844 Prod = InsertBinop(Instruction::Shl, Prod,
841 ConstantInt::get(Ty, RHS->logBase2()),
842 S->getNoWrapFlags(), /*IsSafeToHoist*/ true);
845 ConstantInt::get(Ty, RHS->logBase2()), NWFlags,
846 /*IsSafeToHoist*/ true);
843847 } else {
844848 Prod = InsertBinop(Instruction::Mul, Prod, W, S->getNoWrapFlags(),
845849 /*IsSafeToHoist*/ true);
16361636 TestMatchingCanonicalIV(GetAR2, ARBitWidth);
16371637 }
16381638
1639 TEST_F(ScalarEvolutionsTest, SCEVExpanderShlNSW) {
1640
1641 auto checkOneCase = [this](std::string &&str) {
1642 LLVMContext C;
1643 SMDiagnostic Err;
1644 std::unique_ptr M = parseAssemblyString(str, Err, C);
1645
1646 assert(M && "Could not parse module?");
1647 assert(!verifyModule(*M) && "Must have been well formed!");
1648
1649 Function *F = M->getFunction("f");
1650 ASSERT_NE(F, nullptr) << "Could not find function 'f'";
1651
1652 BasicBlock &Entry = F->getEntryBlock();
1653 LoadInst *Load = cast(&Entry.front());
1654 BinaryOperator *And = cast(*Load->user_begin());
1655
1656 ScalarEvolution SE = buildSE(*F);
1657 const SCEV *AndSCEV = SE.getSCEV(And);
1658 EXPECT_TRUE(isa(AndSCEV));
1659 EXPECT_TRUE(cast(AndSCEV)->hasNoSignedWrap());
1660
1661 SCEVExpander Exp(SE, M->getDataLayout(), "expander");
1662 auto *I = cast(Exp.expandCodeFor(AndSCEV, nullptr, And));
1663 EXPECT_EQ(I->getOpcode(), Instruction::Shl);
1664 EXPECT_FALSE(I->hasNoSignedWrap());
1665 };
1666
1667 checkOneCase("define void @f(i16* %arrayidx) { "
1668 " %1 = load i16, i16* %arrayidx "
1669 " %2 = and i16 %1, -32768 "
1670 " ret void "
1671 "} ");
1672
1673 checkOneCase("define void @f(i8* %arrayidx) { "
1674 " %1 = load i8, i8* %arrayidx "
1675 " %2 = and i8 %1, -128 "
1676 " ret void "
1677 "} ");
1678 }
1679
16391680 } // end anonymous namespace
16401681 } // end namespace llvm