[PATCH] D48066: Add one more No-alias case to alias analysis.

JinGu Kang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 12 09:31:12 PDT 2018


jaykang10 updated this revision to Diff 150970.

https://reviews.llvm.org/D48066

Files:
  lib/Analysis/BasicAliasAnalysis.cpp
  test/Analysis/AliasSet/oddnum-sub-index.ll


Index: test/Analysis/AliasSet/oddnum-sub-index.ll
===================================================================
--- /dev/null
+++ test/Analysis/AliasSet/oddnum-sub-index.ll
@@ -0,0 +1,17 @@
+; RUN: opt -basicaa -print-alias-sets -S -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK
+
+ at buf = common local_unnamed_addr global [4 x i8] zeroinitializer, align 1
+
+; CHECK: AliasSet[{{.*}}, 1] must alias, Mod       Pointers: (i8* %arrayidx, 1)
+; CHECK: AliasSet[{{.*}}, 1] must alias, Mod       Pointers: (i8* %arrayidx2, 1)
+define void @test(i32 %idx) {
+entry:
+  %sub = sub nsw i32 3, %idx
+  %idxprom = sext i32 %sub to i64
+  %arrayidx = getelementptr inbounds [4 x i8], [4 x i8]* @buf, i64 0, i64 %idxprom
+  %idxprom1 = sext i32 %idx to i64
+  %arrayidx2 = getelementptr inbounds [4 x i8], [4 x i8]* @buf, i64 0, i64 %idxprom1
+  store i8 1, i8* %arrayidx, align 1
+  store i8 2, i8* %arrayidx2, align 1
+  ret void
+}
Index: lib/Analysis/BasicAliasAnalysis.cpp
===================================================================
--- lib/Analysis/BasicAliasAnalysis.cpp
+++ lib/Analysis/BasicAliasAnalysis.cpp
@@ -1806,6 +1806,30 @@
   }
 }
 
+static bool checkFormOddNumSubOffset(const Value *V1, const Value *V2,
+                                     unsigned BitWidth, const DataLayout &DL) {
+  if (const BinaryOperator *BOp = dyn_cast<BinaryOperator>(V1)) {
+    if (BOp->getOpcode() != Instruction::Sub)
+      return false;
+
+    if (BOp->getOperand(1) != V2)
+      return false;
+
+    KnownBits KnownLHS = computeKnownBits(BOp->getOperand(0), DL);
+    KnownBits KnownRHS = computeKnownBits(BOp->getOperand(1), DL);
+
+    if (KnownLHS.Zero.countTrailingZeros() ==
+            (KnownRHS.Zero.shl(1) | 1).countTrailingZeros() &&
+        KnownLHS.One.countTrailingOnes() ==
+            KnownRHS.One.shl(1).countTrailingOnes())
+      return false;
+
+    return true;
+  }
+
+  return false;
+}
+
 bool BasicAAResult::constantOffsetHeuristic(
     const SmallVectorImpl<VariableGEPIndex> &VarIndices, LocationSize V1Size,
     LocationSize V2Size, int64_t BaseOffset, AssumptionCache *AC,
@@ -1838,9 +1862,33 @@
                                         V1SExtBits, DL, 0, AC, DT, NSW, NUW);
 
   if (V0Scale != V1Scale || V0ZExtBits != V1ZExtBits ||
-      V0SExtBits != V1SExtBits || !isValueEqualInPotentialCycles(V0, V1))
+      V0SExtBits != V1SExtBits)
     return false;
 
+  if (!isValueEqualInPotentialCycles(V0, V1)) {
+    // Let's look at following C code snippet.
+    //
+    // char buf[4];
+    // int idx = any value;
+    // char *a = buf[3 - idx];
+    // char *b = buf[idx];
+    //
+    // a and b are not aliased. As a result, if the offsets has form as below,
+    // we can say it is not aliased.
+    //
+    // offset1 = odd number - index;
+    // offset2 = index;
+    if (V1Size != V2Size)
+      return false;
+
+    unsigned BitWidth = V1Offset.getBitWidth();
+    if (checkFormOddNumSubOffset(V0, V1, BitWidth, DL) ||
+        checkFormOddNumSubOffset(V1, V0, BitWidth, DL))
+      return true;
+
+    return false;
+  }
+
   // We have a hit - Var0 and Var1 only differ by a constant offset!
 
   // If we've been sext'ed then zext'd the maximum difference between Var0 and


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48066.150970.patch
Type: text/x-patch
Size: 3232 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180612/ed671f92/attachment.bin>


More information about the llvm-commits mailing list