[llvm] [Attributor] Change allocation size and load/store offsets using AAPointerInfo for Alloca instructions (PR #72029)

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 22 11:51:52 PDT 2024


================
@@ -6285,12 +6343,106 @@ struct AAAllocationInfo : public StateWrapper<BooleanState, AbstractAttribute> {
     return AbstractAttribute::isValidIRPositionForInit(A, IRP);
   }
 
+  // A helper function to check if simplified values exists for the current
+  // instruction.
+  // TODO: handle case for a similified value
+  // Right now we don't change the value and give up
+  // on modifying the size and offsets of the allocation
+  // this may be sub-optimal
+  bool checkIfSimplifiedValuesExists(Attributor &A, Instruction *LocalInst) {
+
+    // If there are potential values that replace the accessed instruction, we
+    // should use those instead
+    bool UsedAssumedInformation = false;
+    SmallVector<AA::ValueAndContext> Values;
+    if (A.getAssumedSimplifiedValues(IRPosition::inst(*LocalInst), *this,
+                                     Values, AA::AnyScope,
+                                     UsedAssumedInformation))
+
+      for (auto &ValAndContext : Values)
+        // don't modify instruction if any simplified value exists
+        if (ValAndContext.getValue() && ValAndContext.getValue() != LocalInst)
+          return true;
+
+    return false;
+  }
+
+  // A helper function to back track the pointer operand to
+  // a GEP that calculates the pointer operand from the original allocation.
+  // So that we can correct the type of the GEP.
+  // If such a GEP is not found, we return nullptr.
+  Instruction *
+  backTrackPointerOperandToGepFromAllocation(Instruction *PointerOperand,
+                                             Instruction *Allocation) {
+
+    SmallVector<Instruction *> ReadyList;
+    ReadyList.push_back(PointerOperand);
+    while (!ReadyList.empty()) {
+      Instruction *Back = ReadyList.back();
+      ReadyList.pop_back();
+
+      if (Back == Allocation)
+        continue;
+
+      for (auto *It = Back->op_begin(); It != Back->op_end(); It++) {
+        Instruction *OperandInstruction = dyn_cast<Instruction>(It);
+
+        if (!OperandInstruction)
+          continue;
+
+        // This is the GEP instruction whose type and offsets we can change
+        // without any illegal memory access or poison result.
+        if (Back->getOpcode() == Instruction::GetElementPtr &&
+            OperandInstruction == Allocation)
+          return Back;
+
+        ReadyList.push_back(OperandInstruction);
----------------
jdoerfert wrote:

This goes explore in ways you don't want it, for example
```
%ptrOp = call @foo(%why, %would, %we, %traverse, %all, %of, %these)
```
or 
```
%unrelated = load %allocation
%ptrOp = gep %something, i32 %unrelated
```

You need to check what instruction it is and decide how to traverse it.

Also `Back->getOpcode() == Instruction::GetElementPtr` -> `isa<GetElementPtr>(Back)`


https://github.com/llvm/llvm-project/pull/72029


More information about the llvm-commits mailing list