[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 02:50:35 PDT 2018


jaykang10 created this revision.
jaykang10 added reviewers: eli.friedman, llvm-commits.

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;


Repository:
  rL LLVM

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,28 @@
   }
 }
 
+static bool checkFormOddNumSubOffset(const Value *V1, const Value *V2,
+                                     unsigned BitWidth) {
+  if (const BinaryOperator *BOp = dyn_cast<BinaryOperator>(V1)) {
+    if (ConstantInt *LHSC = dyn_cast<ConstantInt>(BOp->getOperand(0))) {
+      APInt LHS = LHSC->getValue().zextOrSelf(BitWidth);
+      // Check odd number.
+      if ((LHS.getLoBits(1)) == 0) {
+        return false;
+      }
+
+      // Check sub with same object.
+      if (BOp->getOpcode() == Instruction::Sub) {
+        if (BOp->getOperand(1) == V2) {
+          return true;
+        }
+      }
+    }
+  }
+
+  return false;
+}
+
 bool BasicAAResult::constantOffsetHeuristic(
     const SmallVectorImpl<VariableGEPIndex> &VarIndices, LocationSize V1Size,
     LocationSize V2Size, int64_t BaseOffset, AssumptionCache *AC,
@@ -1838,8 +1860,34 @@
                                         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) ||
+        checkFormOddNumSubOffset(V1, V0, BitWidth)) {
+      return true;
+    }
+
     return false;
+  }
 
   // We have a hit - Var0 and Var1 only differ by a constant offset!
 


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


More information about the llvm-commits mailing list