@@ -159,6 +159,8 @@ class IndVarSimplify {
159159
160160 bool sinkUnusedInvariants (Loop *L);
161161
162+ bool simplifyNoOpPHINodeUsers (Loop *L);
163+
162164public:
163165 IndVarSimplify (LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT,
164166 const DataLayout &DL, TargetLibraryInfo *TLI,
@@ -1869,6 +1871,161 @@ bool IndVarSimplify::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
18691871 return Changed;
18701872}
18711873
1874+ static BasicBlock *getSCEVCheckBB (Function &F) {
1875+ for (BasicBlock &BB : F)
1876+ if (BB.getName () == " vector.scevcheck" )
1877+ return &BB;
1878+
1879+ return nullptr ;
1880+ }
1881+
1882+ // Use vector.check block to determine if we can eliminate a bounds check on
1883+ // the IV if we know that we can only enter the vector block if the tripcount
1884+ // is within certain bounds.
1885+ static bool tryElimAndMaskOnPHI (Loop *L, Instruction *AndInstr, PHINode *IndVar,
1886+ ScalarEvolution *SE, Function *F) {
1887+ Value *Op0 = AndInstr->getOperand (0 );
1888+ Value *Op1 = AndInstr->getOperand (1 );
1889+
1890+ auto *Mask = dyn_cast<ConstantInt>(Op0 == IndVar ? Op1 : Op0);
1891+ if (!Mask)
1892+ return false ;
1893+
1894+ auto CheckConditional = [](BranchInst *BranchI, CmpInst *CmpI,
1895+ unsigned ExpectedPred, BasicBlock *Header,
1896+ BasicBlock *PreHeader, Loop *L,
1897+ Value *LatchCmpV) -> bool {
1898+ // Make sure that the conditional operator is what we
1899+ // expect
1900+ unsigned CmpIOpcode = CmpI->getPredicate ();
1901+ if (CmpIOpcode != ExpectedPred)
1902+ return false ;
1903+
1904+ // Check that in the case of a true result we actually
1905+ // branch to the loop
1906+ Value *TrueDest = BranchI->getOperand (1 );
1907+ if (TrueDest != PreHeader && TrueDest != Header)
1908+ return false ;
1909+
1910+ // Check that the conditional variable that is used for the
1911+ // SCEV check is actually used in the latch compare instruction
1912+ auto *LatchCmpInst = L->getLatchCmpInst ();
1913+ if (!LatchCmpInst)
1914+ return false ;
1915+
1916+ if (LatchCmpInst->getOperand (0 ) != LatchCmpV &&
1917+ LatchCmpInst->getOperand (1 ) != LatchCmpV) {
1918+ return false ;
1919+ }
1920+
1921+ return true ;
1922+ };
1923+
1924+ // Determine if there's a runtime SCEV check block
1925+ // and use that to determine if we can elim the phinode
1926+ if (auto *SCEVCheckBB = getSCEVCheckBB (*F)) {
1927+ // Determine if the SCEV check BB branches to the loop preheader
1928+ // or header
1929+ BasicBlock *PreHeader = L->getLoopPreheader ();
1930+ BasicBlock *Header = L->getHeader ();
1931+ if (PreHeader && PreHeader->getUniquePredecessor () != SCEVCheckBB &&
1932+ Header != SCEVCheckBB)
1933+ return false ;
1934+
1935+ // We're interested in a SCEV check block with a branch instruction
1936+ // terminator
1937+ if (auto *BranchI = dyn_cast<BranchInst>(SCEVCheckBB->getTerminator ())) {
1938+ if (!BranchI->isConditional ())
1939+ return false ;
1940+
1941+ Value *Condition = BranchI->getCondition ();
1942+ if (auto *CmpI = dyn_cast<CmpInst>(Condition)) {
1943+ // Check if the condition for the terminating instruction
1944+ // is doing some comparison with a constant integer. If not
1945+ // we can't elim our AND mask
1946+ Value *CmpOp0 = CmpI->getOperand (0 );
1947+ Value *CmpOp1 = CmpI->getOperand (1 );
1948+ auto *CmpConstant = (dyn_cast<ConstantInt>(CmpOp0))
1949+ ? dyn_cast<ConstantInt>(CmpOp0)
1950+ : dyn_cast<ConstantInt>(CmpOp1);
1951+ if (!CmpConstant)
1952+ return false ;
1953+
1954+ if ((CmpConstant == CmpOp1 &&
1955+ CheckConditional (BranchI, CmpI, CmpInst::ICMP_UGT, Header,
1956+ PreHeader, L, CmpOp0)) ||
1957+ (CmpConstant == CmpOp0 &&
1958+ CheckConditional (BranchI, CmpI, CmpInst::ICMP_ULT, Header,
1959+ PreHeader, L, CmpOp1))) {
1960+
1961+ // TODO: inverse operation needs to be checked
1962+ // We can eliminate the AND mask
1963+ if (CmpConstant->uge (Mask->getZExtValue ())) {
1964+ AndInstr->replaceAllUsesWith (IndVar);
1965+ return true ;
1966+ }
1967+ }
1968+ }
1969+ }
1970+ }
1971+
1972+ return false ;
1973+ }
1974+
1975+ static bool tryElimPHINodeUsers (Loop *L, PHINode *PN, ScalarEvolution *SE,
1976+ Function *F) {
1977+ bool Changed = false ;
1978+ for (auto *U : PN->users ()) {
1979+ auto *I = dyn_cast<Instruction>(U);
1980+ switch (I->getOpcode ()) {
1981+ case Instruction::And:
1982+ if (tryElimAndMaskOnPHI (L, I, PN, SE, F)) {
1983+ Changed |= true ;
1984+ }
1985+ break ;
1986+ default :
1987+ break ;
1988+ }
1989+ }
1990+ return Changed;
1991+ }
1992+
1993+ // Attemps to spot and eliminate no-op operations in loop bodies.
1994+ // For example loop Vectorization may create loops like the following.
1995+ //
1996+ // vector.scevcheck:
1997+ // %1 = add i64 %flatten.tripcount, -1
1998+ // %2 = icmp ugt i64 %1, 4294967295
1999+ // br i1 %2, label %scalar.ph, label %vector.ph
2000+ // vector.ph:
2001+ // %iv = phi i64 [ 0, %vector.scevcheck], [ %iv.next, %vector.ph ]
2002+ // %m = and i64 %iv, 4294967295 ; 0xffff_fffe no op
2003+ // %p = getelementptr inbounds <4 x i32>, ptr %A, i64 %m
2004+ // %load = load <4 x i32>, ptr %p, align 4
2005+ // %1 = add <4 x i32> %load, %X
2006+ // store <4 x i32> %1, ptr %p, align 4
2007+ // %iv.next = add nuw i64 %iv, 4
2008+ // %c = icmp ult i64 %iv.next, %N
2009+ // br i1 %c, label %vector.ph, label %exit
2010+ // exit:
2011+ // ret void
2012+ //
2013+ // The vectorizer creates the SCEV check block to perform
2014+ // runtime IV checks. This block can be used to determine true
2015+ // range of the the IV as entry into the vector loop is only possible
2016+ // for certain tripcount values.
2017+ //
2018+ // Currently this only supports spotting no-op AND operations in loop
2019+ // bodies.
2020+ bool IndVarSimplify::simplifyNoOpPHINodeUsers (Loop *L) {
2021+ bool Changed = false ;
2022+ for (BasicBlock *BB : L->blocks ())
2023+ for (Instruction &I : *BB)
2024+ if (auto *PN = dyn_cast<PHINode>(&I))
2025+ Changed |= tryElimPHINodeUsers (L, PN, SE, L->getHeader ()->getParent ());
2026+
2027+ return Changed;
2028+ }
18722029// ===----------------------------------------------------------------------===//
18732030// IndVarSimplify driver. Manage several subpasses of IV simplification.
18742031// ===----------------------------------------------------------------------===//
@@ -1909,6 +2066,7 @@ bool IndVarSimplify::run(Loop *L) {
19092066 // set no-wrap flags before normalizing sign/zero extension.
19102067 Rewriter.disableCanonicalMode ();
19112068 Changed |= simplifyAndExtend (L, Rewriter, LI);
2069+ Changed |= simplifyNoOpPHINodeUsers (L);
19122070
19132071 // Check to see if we can compute the final value of any expressions
19142072 // that are recurrent in the loop, and substitute the exit values from the
0 commit comments