summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2014-12-04 09:22:28 +0000
committerHal Finkel <hfinkel@anl.gov>2014-12-04 09:22:28 +0000
commit8b24b32c44d77ca3121240a13e0f40cb6d5a766c (patch)
tree70b96d9a6edaed06d7fbea0a0aba82ceaf5590b1 /llvm
parent003fc7f4bbcf18c517c8fbed5b88831d01a224bb (diff)
downloadbcm5719-llvm-8b24b32c44d77ca3121240a13e0f40cb6d5a766c.tar.gz
bcm5719-llvm-8b24b32c44d77ca3121240a13e0f40cb6d5a766c.zip
Restrict somewhat the memory-allocation pointer cmp opt from r223093
Based on review comments from Richard Smith, restrict this optimization from applying to globals that might resolve lazily to other dynamically-loaded modules, and also from dynamic allocas (which might be transformed into malloc calls). In short, take extra care that the compared-to pointer is really simultaneously live with the memory allocation. llvm-svn: 223347
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp16
-rw-r--r--llvm/test/Transforms/InstSimplify/noalias-ptr.ll153
2 files changed, 165 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 85ebf694e69..51a295aa5b4 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2026,12 +2026,22 @@ static Constant *computePointerICmp(const DataLayout *DL,
};
// Is the set of underlying objects all things which must be disjoint from
- // noalias calls.
+ // noalias calls. For allocas, we consider only static ones (dynamic
+ // allocas might be transformed into calls to malloc not simultaneously
+ // live with the compared-to allocation). For globals, we exclude symbols
+ // that might be resolve lazily to symbols in another dynamically-loaded
+ // library (and, thus, could be malloc'ed by the implementation).
auto IsAllocDisjoint = [](SmallVectorImpl<Value *> &Objects) {
return std::all_of(Objects.begin(), Objects.end(),
[](Value *V){
- if (isa<AllocaInst>(V) || isa<GlobalValue>(V))
- return true;
+ if (const AllocaInst *AI = dyn_cast<AllocaInst>(V))
+ return AI->isStaticAlloca();
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
+ return (GV->hasLocalLinkage() ||
+ GV->hasHiddenVisibility() ||
+ GV->hasProtectedVisibility() ||
+ GV->hasUnnamedAddr()) &&
+ !GV->isThreadLocal();
if (const Argument *A = dyn_cast<Argument>(V))
return A->hasByValAttr();
return false;
diff --git a/llvm/test/Transforms/InstSimplify/noalias-ptr.ll b/llvm/test/Transforms/InstSimplify/noalias-ptr.ll
index e3435097880..7693e554235 100644
--- a/llvm/test/Transforms/InstSimplify/noalias-ptr.ll
+++ b/llvm/test/Transforms/InstSimplify/noalias-ptr.ll
@@ -3,6 +3,11 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@g1 = global i32 0, align 4
+@g2 = internal global i32 0, align 4
+@g3 = unnamed_addr global i32 0, align 4
+@g4 = hidden global i32 0, align 4
+@g5 = protected global i32 0, align 4
+@g6 = thread_local unnamed_addr global i32 0, align 4
; Make sure we can simplify away a pointer comparison between
; dynamically-allocated memory and a local stack allocation.
@@ -43,7 +48,7 @@ define void @_Z2p2bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
%mStackData = alloca [10 x i32], align 16
%1 = bitcast [10 x i32]* %mStackData to i8*
%2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
- %3 = select i1 %b1, i32* %2, i32* @g1
+ %3 = select i1 %b1, i32* %2, i32* @g2
%4 = tail call noalias i8* @_Znam(i64 48) #4
%5 = tail call noalias i8* @_Znam(i64 48) #4
%.v = select i1 %b2, i8* %4, i8* %5
@@ -64,6 +69,81 @@ define void @_Z2p2bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
ret void
}
+define void @_Z2p4bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* @g3
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z2p4bb
+; CHECK-NOT: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
+define void @_Z2p5bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* @g4
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z2p5bb
+; CHECK-NOT: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
+define void @_Z2p6bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* @g5
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z2p6bb
+; CHECK-NOT: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
; Here's another case involving multiple underlying objects, but this time we
; must keep the comparison (it might involve a regular pointer-typed function
; argument).
@@ -93,6 +173,77 @@ define void @_Z4nopebbPi(i1 zeroext %b1, i1 zeroext %b2, i32* readnone %q) #0 {
ret void
}
+define void @_Z2p3bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* @g1
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z2p3bb
+; CHECK: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
+define void @_Z2p7bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* @g6
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z2p7bb
+; CHECK: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
+define void @_Z2p2v(i32 %c) #0 {
+ %mStackData = alloca [10 x i32], i32 %c, align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = tail call noalias i8* @_Znam(i64 48) #4
+ %3 = bitcast i8* %2 to i32*
+ %4 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %5 = icmp eq i32* %3, %4
+ br i1 %5, label %7, label %6
+
+; CHECK-LABEL: @_Z2p2v
+; CHECK: icmp
+; CHECK: ret void
+
+; <label>:6 ; preds = %0
+ call void @_ZdaPv(i8* %2) #5
+ br label %7
+
+; <label>:7 ; preds = %0, %6
+ ret void
+}
+
; Function Attrs: nobuiltin
declare noalias i8* @_Znam(i64) #2
OpenPOWER on IntegriCloud