[PATCH] D22184: llvm.noalias - don't look through it to simplify GEPs

Hal Finkel via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 8 18:30:41 PDT 2016


hfinkel created this revision.
hfinkel added reviewers: chandlerc, dberlin.
hfinkel added a subscriber: llvm-commits.
Herald added a subscriber: mcrosier.

This is an important case where we shouldn't look through llvm.noalias intrinsics when stripping pointer casts; when simplifying GEPs in InstCombine. If we did, then we always end up replacing the GEP pointer argument with the (simplified) pointer argument of the llvm.noalias intrinsic. Doing that destroys the information that the noalias intrinsic is providing about the pointer value.

http://reviews.llvm.org/D22184

Files:
  include/llvm/IR/Value.h
  lib/IR/Value.cpp
  lib/Transforms/InstCombine/InstructionCombining.cpp
  test/Transforms/InstCombine/noalias.ll

Index: test/Transforms/InstCombine/noalias.ll
===================================================================
--- /dev/null
+++ test/Transforms/InstCombine/noalias.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+ at g = global i32* null
+
+define i32 @test1(i32* %q, i32* %p, i1 %b) {
+  %pa = tail call i32* @llvm.noalias.p0i32(i32* %p, metadata !0)
+  %tmp2 = getelementptr inbounds i32, i32* %pa, i64 2
+  %val = load i32, i32* %tmp2, align 4
+  store i32 0, i32* %pa, align 4
+  store i32* %q, i32** @g, align 8
+  ret i32 %val
+
+; CHECK-LABEL: @test1
+; CHECK: call i32* @llvm.noalias.p0i32
+; CHECK: getelementptr inbounds i32, i32* %pa, i64 2
+; CHECK: ret i32
+}
+
+declare i32* @llvm.noalias.p0i32(i32*, metadata) nounwind
+
+!0 = !{!0, !"some domain"}
+!1 = !{!1, !0, !"some scope"}
Index: lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- lib/Transforms/InstCombine/InstructionCombining.cpp
+++ lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1605,7 +1605,7 @@
   }
 
   // Handle gep(bitcast x) and gep(gep x, 0, 0, 0).
-  Value *StrippedPtr = PtrOp->stripPointerCasts();
+  Value *StrippedPtr = PtrOp->stripPointerCastsExceptNoAlias();
   PointerType *StrippedPtrTy = dyn_cast<PointerType>(StrippedPtr->getType());
 
   // We do not handle pointer-vector geps here.
Index: lib/IR/Value.cpp
===================================================================
--- lib/IR/Value.cpp
+++ lib/IR/Value.cpp
@@ -429,7 +429,7 @@
 };
 
 template <PointerStripKind StripKind>
-static Value *stripPointerCastsAndOffsets(Value *V) {
+static Value *stripPointerCastsAndOffsets(Value *V, bool StripNoAlias = true) {
   if (!V->getType()->isPointerTy())
     return V;
 
@@ -465,7 +465,7 @@
       V = GA->getAliasee();
     } else {
       if (IntrinsicInst *I = dyn_cast<IntrinsicInst>(V))
-        if (I->getIntrinsicID() == Intrinsic::noalias) {
+        if (StripNoAlias && I->getIntrinsicID() == Intrinsic::noalias) {
           V = I->getOperand(0);
           continue;
         }
@@ -487,6 +487,10 @@
   return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this);
 }
 
+Value *Value::stripPointerCastsExceptNoAlias() {
+  return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliases>(this, false);
+}
+
 Value *Value::stripInBoundsConstantOffsets() {
   return stripPointerCastsAndOffsets<PSK_InBoundsConstantIndices>(this);
 }
Index: include/llvm/IR/Value.h
===================================================================
--- include/llvm/IR/Value.h
+++ include/llvm/IR/Value.h
@@ -480,6 +480,16 @@
     return const_cast<Value*>(this)->stripInBoundsConstantOffsets();
   }
 
+  /// \brief Strip off pointer casts and all-zero GEPs without stripping
+  /// @llvm.noalias intrinsics.
+  ///
+  /// Returns the original uncasted value.  If this is called on a non-pointer
+  /// value, it returns 'this'.
+  Value *stripPointerCastsExceptNoAlias();
+  const Value *stripPointerCastsExceptNoAlias() const {
+    return const_cast<Value*>(this)->stripPointerCastsExceptNoAlias();
+  }
+
   /// \brief Accumulate offsets from \a stripInBoundsConstantOffsets().
   ///
   /// Stores the resulting constant offset stripped into the APInt provided.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D22184.63368.patch
Type: text/x-patch
Size: 3321 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160709/a6606410/attachment.bin>


More information about the llvm-commits mailing list