[llvm] [BasicAA] Handle wrapping of pointer arithmetic (PR #69116)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 15 09:55:00 PDT 2023


https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/69116

This PR handles wrapping of pointer arithmetic conservatively, which is introduced by `InstCombine` (the behavior of C source code is well-defined).

Fixes #69096.

TBH, I think this workaround solution is ugly (and buggy?). Please let me know if you have a better one.


>From af001c378bae17ea2a237130079a847418a47548 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 16 Oct 2023 00:32:54 +0800
Subject: [PATCH 1/2] [BasicAA] Add pre-commit tests for PR69096. NFC.

---
 llvm/test/Analysis/BasicAA/pr69096.ll | 31 +++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 llvm/test/Analysis/BasicAA/pr69096.ll

diff --git a/llvm/test/Analysis/BasicAA/pr69096.ll b/llvm/test/Analysis/BasicAA/pr69096.ll
new file mode 100644
index 000000000000000..7d8506b81c2bfbf
--- /dev/null
+++ b/llvm/test/Analysis/BasicAA/pr69096.ll
@@ -0,0 +1,31 @@
+; RUN: opt %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+target datalayout = "p:64:64:64"
+
+; CHECK-LABEL: Function: pr69096
+; FIXME: This should be MayAlias. %p == %scevgep.i when %a == -1.
+; CHECK: NoAlias:     i8* %p, i16* %scevgep.i
+
+define i32 @pr69096(i16 %a, ptr %p) {
+entry:
+  %0 = load i8, ptr %p, align 2
+  %dec.i = add i8 %0, -1
+  %cmp636.i = icmp eq i16 %a, -1
+  br i1 %cmp636.i, label %for.cond2.for.inc29_crit_edge.i, label %n.exit
+
+for.cond2.for.inc29_crit_edge.i:
+  %conv3.i = zext i16 %a to i64
+  %sub.i.i = shl i64 %conv3.i, 56
+  %sub21.i = shl nuw nsw i64 %conv3.i, 2
+  %1 = getelementptr i8, ptr %p, i64 %sub21.i
+  %2 = getelementptr i8, ptr %1, i64 -262140
+  %3 = getelementptr i8, ptr %2, i64 %sub.i.i
+  %scevgep.i = getelementptr i8, ptr %3, i64 72057594037927936
+  store i16 1285, ptr %scevgep.i, align 2
+  br label %n.exit
+
+n.exit:
+  %4 = load i8, ptr %p, align 2
+  %conv = sext i8 %4 to i32
+  ret i32 %conv
+}

>From d1b85b874d6242adb15087c43b295b0bb3024d38 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 16 Oct 2023 00:41:26 +0800
Subject: [PATCH 2/2] [BasicAA] Handle wrapping of pointer arithmetic

---
 llvm/lib/Analysis/BasicAliasAnalysis.cpp            | 9 +++++++--
 llvm/test/Analysis/BasicAA/assume-index-positive.ll | 2 +-
 llvm/test/Analysis/BasicAA/gep-modulo.ll            | 4 ++--
 llvm/test/Analysis/BasicAA/pr69096.ll               | 3 +--
 4 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index c162b8f6edc1905..a19524b527682f3 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -417,7 +417,8 @@ static LinearExpression GetLinearExpression(
                                 Depth + 1, AC, DT);
         E.Offset <<= RHS.getLimitedValue();
         E.Scale <<= RHS.getLimitedValue();
-        E.IsNSW &= NSW;
+        // The nsw flag has different semantics for shift and mul.
+        E.IsNSW = false;
         break;
       }
       return E;
@@ -1184,7 +1185,11 @@ AliasResult BasicAAResult::aliasGEP(
   APInt ModOffset = DecompGEP1.Offset.srem(GCD);
   if (ModOffset.isNegative())
     ModOffset += GCD; // We want mod, not rem.
-  if (ModOffset.uge(V2Size.getValue()) &&
+  unsigned PtrBW =
+      DL.getPointerSizeInBits(GEP1->getType()->getPointerAddressSpace());
+  if ((GCD.isPowerOf2() || !OffsetRange.sextOrTrunc(PtrBW).isFullSet() ||
+       (*DecompGEP1.InBounds && DecompGEP2.InBounds == true)) &&
+      ModOffset.uge(V2Size.getValue()) &&
       (GCD - ModOffset).uge(V1Size.getValue()))
     return AliasResult::NoAlias;
 
diff --git a/llvm/test/Analysis/BasicAA/assume-index-positive.ll b/llvm/test/Analysis/BasicAA/assume-index-positive.ll
index 42014dfe0264218..d5a7b540266b6cf 100644
--- a/llvm/test/Analysis/BasicAA/assume-index-positive.ll
+++ b/llvm/test/Analysis/BasicAA/assume-index-positive.ll
@@ -116,7 +116,7 @@ define void @shl_of_non_negative(ptr %ptr, i64 %a) {
 define void @shl_nsw_of_non_negative(ptr %ptr, i64 %a) {
 ; CHECK-LABEL: Function: shl_nsw_of_non_negative
 ; CHECK: NoAlias: i8* %ptr.a, i8* %ptr.neg
-; CHECK: NoAlias: i8* %ptr.neg, i8* %ptr.shl
+; CHECK: MayAlias: i8* %ptr.neg, i8* %ptr.shl
 ;
   %a.cmp = icmp sge i64 %a, 0
   call void @llvm.assume(i1 %a.cmp)
diff --git a/llvm/test/Analysis/BasicAA/gep-modulo.ll b/llvm/test/Analysis/BasicAA/gep-modulo.ll
index dcbc0a9090852e4..7c8c1f3b3ee34d2 100644
--- a/llvm/test/Analysis/BasicAA/gep-modulo.ll
+++ b/llvm/test/Analysis/BasicAA/gep-modulo.ll
@@ -90,7 +90,7 @@ define void @nuw_nsw_mul_sub_i64(ptr %ptr, i64 %idx) {
 ; CHECK-LABEL: Function: nuw_nsw_mul_sub_i64: 3 pointers, 0 call sites
 ; CHECK-NEXT:    MayAlias:  i8* %gep.idx, [16 x i8]* %ptr
 ; CHECK-NEXT:    PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
-; CHECK-NEXT:    NoAlias:  i8* %gep.3, i8* %gep.idx
+; CHECK-NEXT:    MayAlias:  i8* %gep.3, i8* %gep.idx
 ;
   load [16 x i8], ptr %ptr
   %mul = mul nuw nsw i64 %idx, 5
@@ -106,7 +106,7 @@ define void @only_nsw_mul_sub_i64(ptr %ptr, i64 %idx) {
 ; CHECK-LABEL: Function: only_nsw_mul_sub_i64: 3 pointers, 0 call sites
 ; CHECK-NEXT:    MayAlias:  i8* %gep.idx, [16 x i8]* %ptr
 ; CHECK-NEXT:    PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
-; CHECK-NEXT:    NoAlias:  i8* %gep.3, i8* %gep.idx
+; CHECK-NEXT:    MayAlias:  i8* %gep.3, i8* %gep.idx
 ;
   load [16 x i8], ptr %ptr
   %mul = mul nsw i64 %idx, 5
diff --git a/llvm/test/Analysis/BasicAA/pr69096.ll b/llvm/test/Analysis/BasicAA/pr69096.ll
index 7d8506b81c2bfbf..a55cfaff45a2bd9 100644
--- a/llvm/test/Analysis/BasicAA/pr69096.ll
+++ b/llvm/test/Analysis/BasicAA/pr69096.ll
@@ -3,8 +3,7 @@
 target datalayout = "p:64:64:64"
 
 ; CHECK-LABEL: Function: pr69096
-; FIXME: This should be MayAlias. %p == %scevgep.i when %a == -1.
-; CHECK: NoAlias:     i8* %p, i16* %scevgep.i
+; CHECK: MayAlias:     i8* %p, i16* %scevgep.i
 
 define i32 @pr69096(i16 %a, ptr %p) {
 entry:



More information about the llvm-commits mailing list