[clang] [llvm] [BasicAA] Do not decompose past casts with different index width (PR #119365)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 9 01:17:54 PST 2025


nikic wrote:

It's expected that there are regressions if you are mixing pointers with different index widths. I'm open to ideas, but I don't see any obvious way we can fully support pointers with different index widths while also being correct. A key thing that BasicAA needs is the ability to subtract two GEPs, and I'm not even sure what that is supposed to mean when different index widths are involved (it would be easy if we didn't have to care about overflow, but unfortunately this is something BasicAA must model accurately).

It would be easy to support your specific example with a patch like the following, effectively modelling this as a failure to subtract the GEPs. Does that help you in practice? I don't know if your example was over-reduced.

```diff
>From a0ebbaf72745218f89e45e8e7cc4365773673b05 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 9 Jan 2025 10:09:28 +0100
Subject: [PATCH] gep diff

---
 .../llvm/Analysis/BasicAliasAnalysis.h        |  2 +-
 llvm/lib/Analysis/BasicAliasAnalysis.cpp      | 19 ++++++++++++-------
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/llvm/include/llvm/Analysis/BasicAliasAnalysis.h b/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
index 7eca82729430..b81324f8da46 100644
--- a/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
+++ b/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
@@ -122,7 +122,7 @@ private:
   bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2,
                                      const AAQueryInfo &AAQI);
 
-  void subtractDecomposedGEPs(DecomposedGEP &DestGEP,
+  bool subtractDecomposedGEPs(DecomposedGEP &DestGEP,
                               const DecomposedGEP &SrcGEP,
                               const AAQueryInfo &AAQI);
 
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index b2a3f3390e00..70b173a3785b 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1090,10 +1090,6 @@ AliasResult BasicAAResult::aliasGEP(
   if (DecompGEP1.Base == GEP1 && DecompGEP2.Base == V2)
     return AliasResult::MayAlias;
 
-  // Fall back to base objects if pointers have different index widths.
-  if (DecompGEP1.Offset.getBitWidth() != DecompGEP2.Offset.getBitWidth())
-    return BaseObjectsAlias();
-
   // Swap GEP1 and GEP2 if GEP2 has more variable indices.
   if (DecompGEP1.VarIndices.size() < DecompGEP2.VarIndices.size()) {
     std::swap(DecompGEP1, DecompGEP2);
@@ -1102,8 +1098,9 @@ AliasResult BasicAAResult::aliasGEP(
   }
 
   // Subtract the GEP2 pointer from the GEP1 pointer to find out their
-  // symbolic difference.
-  subtractDecomposedGEPs(DecompGEP1, DecompGEP2, AAQI);
+  // symbolic difference. If we can't, fall back to the base object check.
+  if (!subtractDecomposedGEPs(DecompGEP1, DecompGEP2, AAQI))
+    return BaseObjectsAlias();
 
   // If an inbounds GEP would have to start from an out of bounds address
   // for the two to alias, then we can assume noalias.
@@ -1843,9 +1840,15 @@ bool BasicAAResult::isValueEqualInPotentialCycles(const Value *V,
 }
 
 /// Computes the symbolic difference between two de-composed GEPs.
-void BasicAAResult::subtractDecomposedGEPs(DecomposedGEP &DestGEP,
+bool BasicAAResult::subtractDecomposedGEPs(DecomposedGEP &DestGEP,
                                            const DecomposedGEP &SrcGEP,
                                            const AAQueryInfo &AAQI) {
+  // We do not know how to correctly subtract GEPS with different index widths.
+  // Only handle the case where the RHS is a trivial GEP without indices or
+  // offsets, as there is nothing to subtract in that case.
+  if (DestGEP.Offset.getBitWidth() != SrcGEP.Offset.getBitWidth())
+    return SrcGEP.VarIndices.empty() && SrcGEP.Offset.isZero();
+
   // Drop nuw flag from GEP if subtraction of constant offsets overflows in an
   // unsigned sense.
   if (DestGEP.Offset.ult(SrcGEP.Offset))
@@ -1897,6 +1900,8 @@ void BasicAAResult::subtractDecomposedGEPs(DecomposedGEP &DestGEP,
       DestGEP.NWFlags = DestGEP.NWFlags.withoutNoUnsignedWrap();
     }
   }
+
+  return true;
 }
 
 bool BasicAAResult::constantOffsetHeuristic(const DecomposedGEP &GEP,
-- 
2.47.1
```

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


More information about the llvm-commits mailing list