[llvm] 4f02a0f - [NFC][CodeGenPrepare] Match against the correct instruction when checking profitability of folding an address

Momchil Velikov via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 21 10:10:06 PDT 2023


Author: Momchil Velikov
Date: 2023-04-21T18:09:51+01:00
New Revision: 4f02a0f60693d2abea58a508ea9ae790864a6389

URL: https://github.com/llvm/llvm-project/commit/4f02a0f60693d2abea58a508ea9ae790864a6389
DIFF: https://github.com/llvm/llvm-project/commit/4f02a0f60693d2abea58a508ea9ae790864a6389.diff

LOG: [NFC][CodeGenPrepare] Match against the correct instruction when checking profitability of folding an address

The "nested" `AddressingModeMatcher`s in
`AddressingModeMatcher::isProfitableToFoldIntoAddressingMode` are constructed
using the original memory instruction, even though they check whether the
address operand of a differrent memory instructon is foldable. The memory
instruction is used only for a dominance check (when not checking for
profitability), and using the wrong memory instruction does not change the
outcome of the test - if an address is foldable, the dominance test afects which
of the two possible ways to fold is chosen, but this result is discarded.

As an example, in

    target triple = "x86_64-linux"

    declare i1 @check(i64, i64)
    define i32 @f(i1 %cc, ptr %p, ptr %q, i64 %n) {
    entry:
      br label %loop

    loop:
      %iv = phi i64 [ %i, %C ], [ 0, %entry ]
      %offs = mul i64 %iv, 4

      %c.0 = icmp  ult i64 %iv, %n
      br i1 %c.0, label %A, label %fail

    A:
      br i1 %cc, label %B, label %C

    C:
      %u = phi i32 [0, %A], [%w, %B]
      %i = add i64 %iv, 1
      %a.0 = getelementptr i8, ptr %p, i64 %offs
      %a.1 = getelementptr i8, ptr %a.0, i64 4
      %v = load i32, ptr %a.1
      %c.1 = icmp eq i32 %v, %u
      br i1 %c.1, label %exit, label %loop

    B:
      %a.2 = getelementptr i8, ptr %p, i64 %offs
      %a.3 = getelementptr i8, ptr %a.2, i64 4
      %w = load i32, ptr %a.3
      br label %C

    exit:
      ret i32 -1

    fail:
       ret i32 0
    }

the dominance test is perfomed between `%i = ...` and `%v = ...` at the moment
we're checking whether `%a3 = ...` is foldable

Using the memory instruction, which uses the interesting address is "more
correct" and this change is needed by a future patch.

Reviewed By: mkazantsev

Differential Revision: https://reviews.llvm.org/D143896

Added: 
    

Modified: 
    llvm/lib/CodeGen/CodeGenPrepare.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 95cad24c9e92..c7831827d11e 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -4976,7 +4976,7 @@ static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal,
 /// If we find an obviously non-foldable instruction, return true.
 /// Add accessed addresses and types to MemoryUses.
 static bool FindAllMemoryUses(
-    Instruction *I, SmallVectorImpl<std::pair<Value *, Type *>> &MemoryUses,
+    Instruction *I, SmallVectorImpl<std::pair<Use *, Type *>> &MemoryUses,
     SmallPtrSetImpl<Instruction *> &ConsideredInsts, const TargetLowering &TLI,
     const TargetRegisterInfo &TRI, bool OptSize, ProfileSummaryInfo *PSI,
     BlockFrequencyInfo *BFI, unsigned &SeenInsts) {
@@ -4997,28 +4997,28 @@ static bool FindAllMemoryUses(
 
     Instruction *UserI = cast<Instruction>(U.getUser());
     if (LoadInst *LI = dyn_cast<LoadInst>(UserI)) {
-      MemoryUses.push_back({U.get(), LI->getType()});
+      MemoryUses.push_back({&U, LI->getType()});
       continue;
     }
 
     if (StoreInst *SI = dyn_cast<StoreInst>(UserI)) {
       if (U.getOperandNo() != StoreInst::getPointerOperandIndex())
         return true; // Storing addr, not into addr.
-      MemoryUses.push_back({U.get(), SI->getValueOperand()->getType()});
+      MemoryUses.push_back({&U, SI->getValueOperand()->getType()});
       continue;
     }
 
     if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(UserI)) {
       if (U.getOperandNo() != AtomicRMWInst::getPointerOperandIndex())
         return true; // Storing addr, not into addr.
-      MemoryUses.push_back({U.get(), RMW->getValOperand()->getType()});
+      MemoryUses.push_back({&U, RMW->getValOperand()->getType()});
       continue;
     }
 
     if (AtomicCmpXchgInst *CmpX = dyn_cast<AtomicCmpXchgInst>(UserI)) {
       if (U.getOperandNo() != AtomicCmpXchgInst::getPointerOperandIndex())
         return true; // Storing addr, not into addr.
-      MemoryUses.push_back({U.get(), CmpX->getCompareOperand()->getType()});
+      MemoryUses.push_back({&U, CmpX->getCompareOperand()->getType()});
       continue;
     }
 
@@ -5051,7 +5051,7 @@ static bool FindAllMemoryUses(
 }
 
 static bool FindAllMemoryUses(
-    Instruction *I, SmallVectorImpl<std::pair<Value *, Type *>> &MemoryUses,
+    Instruction *I, SmallVectorImpl<std::pair<Use *, Type *>> &MemoryUses,
     const TargetLowering &TLI, const TargetRegisterInfo &TRI, bool OptSize,
     ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
   unsigned SeenInsts = 0;
@@ -5142,7 +5142,7 @@ bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
   // we can remove the addressing mode and effectively trade one live register
   // for another (at worst.)  In this context, folding an addressing mode into
   // the use is just a particularly nice way of sinking it.
-  SmallVector<std::pair<Value *, Type *>, 16> MemoryUses;
+  SmallVector<std::pair<Use *, Type *>, 16> MemoryUses;
   if (FindAllMemoryUses(I, MemoryUses, TLI, TRI, OptSize, PSI, BFI))
     return false; // Has a non-memory, non-foldable use!
 
@@ -5156,8 +5156,9 @@ bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
   // growth since most architectures have some reasonable small and fast way to
   // compute an effective address.  (i.e LEA on x86)
   SmallVector<Instruction *, 32> MatchedAddrModeInsts;
-  for (const std::pair<Value *, Type *> &Pair : MemoryUses) {
-    Value *Address = Pair.first;
+  for (const std::pair<Use *, Type *> &Pair : MemoryUses) {
+    Value *Address = Pair.first->get();
+    Instruction *UserI = cast<Instruction>(Pair.first->getUser());
     Type *AddressAccessTy = Pair.second;
     unsigned AS = Address->getType()->getPointerAddressSpace();
 
@@ -5170,7 +5171,7 @@ bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
     TypePromotionTransaction::ConstRestorationPt LastKnownGood =
         TPT.getRestorationPoint();
     AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI, TRI, LI, getDTFn,
-                                  AddressAccessTy, AS, MemoryInst, Result,
+                                  AddressAccessTy, AS, UserI, Result,
                                   InsertedInsts, PromotedInsts, TPT,
                                   LargeOffsetGEP, OptSize, PSI, BFI);
     Matcher.IgnoreProfitability = true;


        


More information about the llvm-commits mailing list