llvm.org GIT mirror llvm / f40be99
Add ScalarEvolutionsTest::SCEVExpandInsertCanonicalIV tests Test insertion of canonical IV in canonical expansion mode. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362432 91177308-0d34-0410-b5e6-96231b3b80d8 Artur Pilipenko a month ago
1 changed file(s) with 193 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
14431443 EXPECT_EQ(S2S->getExpressionSize(), 5u);
14441444 }
14451445
1446 TEST_F(ScalarEvolutionsTest, SCEVExpandInsertCanonicalIV) {
1447 LLVMContext C;
1448 SMDiagnostic Err;
1449
1450 // Expand the addrec produced by GetAddRec into a loop without a canonical IV.
1451 // SCEVExpander will insert one.
1452 auto TestNoCanonicalIV = [&](
1453 std::function GetAddRec) {
1454 std::unique_ptr M =
1455 parseAssemblyString("define i32 @test(i32 %limit) { "
1456 "entry: "
1457 " br label %loop "
1458 "loop: "
1459 " %i = phi i32 [ 1, %entry ], [ %i.inc, %loop ] "
1460 " %i.inc = add nsw i32 %i, 1 "
1461 " %cont = icmp slt i32 %i.inc, %limit "
1462 " br i1 %cont, label %loop, label %exit "
1463 "exit: "
1464 " ret i32 %i.inc "
1465 "}",
1466 Err, C);
1467
1468 assert(M && "Could not parse module?");
1469 assert(!verifyModule(*M) && "Must have been well formed!");
1470
1471 runWithSE(*M, "test", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
1472 auto &I = GetInstByName(F, "i");
1473 auto *Loop = LI.getLoopFor(I.getParent());
1474 EXPECT_FALSE(Loop->getCanonicalInductionVariable());
1475
1476 auto *AR = GetAddRec(SE, Loop);
1477 unsigned ExpectedCanonicalIVWidth = SE.getTypeSizeInBits(AR->getType());
1478
1479 SCEVExpander Exp(SE, M->getDataLayout(), "expander");
1480 auto *InsertAt = I.getNextNode();
1481 Exp.expandCodeFor(AR, nullptr, InsertAt);
1482 PHINode *CanonicalIV = Loop->getCanonicalInductionVariable();
1483 unsigned CanonicalIVBitWidth =
1484 cast(CanonicalIV->getType())->getBitWidth();
1485 EXPECT_EQ(CanonicalIVBitWidth, ExpectedCanonicalIVWidth);
1486 });
1487 };
1488
1489 // Expand the addrec produced by GetAddRec into a loop with a canonical IV
1490 // which is narrower than addrec type.
1491 // SCEVExpander will insert a canonical IV of a wider type to expand the
1492 // addrec.
1493 auto TestNarrowCanonicalIV = [&](
1494 std::function GetAddRec) {
1495 std::unique_ptr M = parseAssemblyString(
1496 "define i32 @test(i32 %limit) { "
1497 "entry: "
1498 " br label %loop "
1499 "loop: "
1500 " %i = phi i32 [ 1, %entry ], [ %i.inc, %loop ] "
1501 " %canonical.iv = phi i8 [ 0, %entry ], [ %canonical.iv.inc, %loop ] "
1502 " %i.inc = add nsw i32 %i, 1 "
1503 " %canonical.iv.inc = add i8 %canonical.iv, 1 "
1504 " %cont = icmp slt i32 %i.inc, %limit "
1505 " br i1 %cont, label %loop, label %exit "
1506 "exit: "
1507 " ret i32 %i.inc "
1508 "}",
1509 Err, C);
1510
1511 assert(M && "Could not parse module?");
1512 assert(!verifyModule(*M) && "Must have been well formed!");
1513
1514 runWithSE(*M, "test", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
1515 auto &I = GetInstByName(F, "i");
1516
1517 auto *LoopHeaderBB = I.getParent();
1518 auto *Loop = LI.getLoopFor(LoopHeaderBB);
1519 PHINode *CanonicalIV = Loop->getCanonicalInductionVariable();
1520 EXPECT_EQ(CanonicalIV, &GetInstByName(F, "canonical.iv"));
1521
1522 auto *AR = GetAddRec(SE, Loop);
1523
1524 unsigned ExpectedCanonicalIVWidth = SE.getTypeSizeInBits(AR->getType());
1525 unsigned CanonicalIVBitWidth =
1526 cast(CanonicalIV->getType())->getBitWidth();
1527 EXPECT_LT(CanonicalIVBitWidth, ExpectedCanonicalIVWidth);
1528
1529 SCEVExpander Exp(SE, M->getDataLayout(), "expander");
1530 auto *InsertAt = I.getNextNode();
1531 Exp.expandCodeFor(AR, nullptr, InsertAt);
1532
1533 // Loop over all of the PHI nodes, looking for the new canonical indvar.
1534 PHINode *NewCanonicalIV = nullptr;
1535 for (BasicBlock::iterator i = LoopHeaderBB->begin(); isa(i);
1536 ++i) {
1537 PHINode *PN = cast(i);
1538 if (PN == &I || PN == CanonicalIV)
1539 continue;
1540 // We expect that the only PHI added is the new canonical IV
1541 EXPECT_FALSE(NewCanonicalIV);
1542 NewCanonicalIV = PN;
1543 }
1544
1545 // Check that NewCanonicalIV is a canonical IV, i.e {0,+,1}
1546 BasicBlock *Incoming = nullptr, *Backedge = nullptr;
1547 EXPECT_TRUE(Loop->getIncomingAndBackEdge(Incoming, Backedge));
1548 auto *Start = NewCanonicalIV->getIncomingValueForBlock(Incoming);
1549 EXPECT_TRUE(isa(Start));
1550 EXPECT_TRUE(dyn_cast(Start)->isZero());
1551 auto *Next = NewCanonicalIV->getIncomingValueForBlock(Backedge);
1552 EXPECT_TRUE(isa(Next));
1553 auto *NextBinOp = dyn_cast(Next);
1554 EXPECT_EQ(NextBinOp->getOpcode(), Instruction::Add);
1555 EXPECT_EQ(NextBinOp->getOperand(0), NewCanonicalIV);
1556 auto *Step = NextBinOp->getOperand(1);
1557 EXPECT_TRUE(isa(Step));
1558 EXPECT_TRUE(dyn_cast(Step)->isOne());
1559
1560 unsigned NewCanonicalIVBitWidth =
1561 cast(NewCanonicalIV->getType())->getBitWidth();
1562 EXPECT_EQ(NewCanonicalIVBitWidth, ExpectedCanonicalIVWidth);
1563 });
1564 };
1565
1566 // Expand the addrec produced by GetAddRec into a loop with a canonical IV
1567 // of addrec width.
1568 // To expand the addrec SCEVExpander should use the existing canonical IV.
1569 auto TestMatchingCanonicalIV = [&](
1570 std::function GetAddRec,
1571 unsigned ARBitWidth) {
1572 auto ARBitWidthTypeStr = "i" + std::to_string(ARBitWidth);
1573 std::unique_ptr M = parseAssemblyString(
1574 "define i32 @test(i32 %limit) { "
1575 "entry: "
1576 " br label %loop "
1577 "loop: "
1578 " %i = phi i32 [ 1, %entry ], [ %i.inc, %loop ] "
1579 " %canonical.iv = phi " + ARBitWidthTypeStr +
1580 " [ 0, %entry ], [ %canonical.iv.inc, %loop ] "
1581 " %i.inc = add nsw i32 %i, 1 "
1582 " %canonical.iv.inc = add " + ARBitWidthTypeStr +
1583 " %canonical.iv, 1 "
1584 " %cont = icmp slt i32 %i.inc, %limit "
1585 " br i1 %cont, label %loop, label %exit "
1586 "exit: "
1587 " ret i32 %i.inc "
1588 "}",
1589 Err, C);
1590
1591 assert(M && "Could not parse module?");
1592 assert(!verifyModule(*M) && "Must have been well formed!");
1593
1594 runWithSE(*M, "test", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
1595 auto &I = GetInstByName(F, "i");
1596 auto &CanonicalIV = GetInstByName(F, "canonical.iv");
1597
1598 auto *LoopHeaderBB = I.getParent();
1599 auto *Loop = LI.getLoopFor(LoopHeaderBB);
1600 EXPECT_EQ(&CanonicalIV, Loop->getCanonicalInductionVariable());
1601 unsigned CanonicalIVBitWidth =
1602 cast(CanonicalIV.getType())->getBitWidth();
1603
1604 auto *AR = GetAddRec(SE, Loop);
1605 EXPECT_EQ(ARBitWidth, SE.getTypeSizeInBits(AR->getType()));
1606 EXPECT_EQ(CanonicalIVBitWidth, ARBitWidth);
1607
1608 SCEVExpander Exp(SE, M->getDataLayout(), "expander");
1609 auto *InsertAt = I.getNextNode();
1610 Exp.expandCodeFor(AR, nullptr, InsertAt);
1611
1612 // Loop over all of the PHI nodes, looking if a new canonical indvar was
1613 // introduced.
1614 PHINode *NewCanonicalIV = nullptr;
1615 for (BasicBlock::iterator i = LoopHeaderBB->begin(); isa(i);
1616 ++i) {
1617 PHINode *PN = cast(i);
1618 if (PN == &I || PN == &CanonicalIV)
1619 continue;
1620 NewCanonicalIV = PN;
1621 }
1622 EXPECT_FALSE(NewCanonicalIV);
1623 });
1624 };
1625
1626 unsigned ARBitWidth = 16;
1627 Type *ARType = IntegerType::get(C, ARBitWidth);
1628
1629 // Expand {5,+,1}
1630 auto GetAR2 = [&](ScalarEvolution &SE, Loop *L) -> const SCEV * {
1631 return SE.getAddRecExpr(SE.getConstant(APInt(ARBitWidth, 5)),
1632 SE.getOne(ARType), L, SCEV::FlagAnyWrap);
1633 };
1634 TestNoCanonicalIV(GetAR2);
1635 TestNarrowCanonicalIV(GetAR2);
1636 TestMatchingCanonicalIV(GetAR2, ARBitWidth);
1637 }
1638
14461639 } // end anonymous namespace
14471640 } // end namespace llvm