Skip to content

Commit 8b24b32

Browse files
author
Hal Finkel
committed
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
1 parent 003fc7f commit 8b24b32

File tree

2 files changed

+165
-4
lines changed

2 files changed

+165
-4
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2026,12 +2026,22 @@ static Constant *computePointerICmp(const DataLayout *DL,
20262026
};
20272027

20282028
// Is the set of underlying objects all things which must be disjoint from
2029-
// noalias calls.
2029+
// noalias calls. For allocas, we consider only static ones (dynamic
2030+
// allocas might be transformed into calls to malloc not simultaneously
2031+
// live with the compared-to allocation). For globals, we exclude symbols
2032+
// that might be resolve lazily to symbols in another dynamically-loaded
2033+
// library (and, thus, could be malloc'ed by the implementation).
20302034
auto IsAllocDisjoint = [](SmallVectorImpl<Value *> &Objects) {
20312035
return std::all_of(Objects.begin(), Objects.end(),
20322036
[](Value *V){
2033-
if (isa<AllocaInst>(V) || isa<GlobalValue>(V))
2034-
return true;
2037+
if (const AllocaInst *AI = dyn_cast<AllocaInst>(V))
2038+
return AI->isStaticAlloca();
2039+
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
2040+
return (GV->hasLocalLinkage() ||
2041+
GV->hasHiddenVisibility() ||
2042+
GV->hasProtectedVisibility() ||
2043+
GV->hasUnnamedAddr()) &&
2044+
!GV->isThreadLocal();
20352045
if (const Argument *A = dyn_cast<Argument>(V))
20362046
return A->hasByValAttr();
20372047
return false;

llvm/test/Transforms/InstSimplify/noalias-ptr.ll

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
33
target triple = "x86_64-unknown-linux-gnu"
44

55
@g1 = global i32 0, align 4
6+
@g2 = internal global i32 0, align 4
7+
@g3 = unnamed_addr global i32 0, align 4
8+
@g4 = hidden global i32 0, align 4
9+
@g5 = protected global i32 0, align 4
10+
@g6 = thread_local unnamed_addr global i32 0, align 4
611

712
; Make sure we can simplify away a pointer comparison between
813
; dynamically-allocated memory and a local stack allocation.
@@ -43,7 +48,7 @@ define void @_Z2p2bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
4348
%mStackData = alloca [10 x i32], align 16
4449
%1 = bitcast [10 x i32]* %mStackData to i8*
4550
%2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
46-
%3 = select i1 %b1, i32* %2, i32* @g1
51+
%3 = select i1 %b1, i32* %2, i32* @g2
4752
%4 = tail call noalias i8* @_Znam(i64 48) #4
4853
%5 = tail call noalias i8* @_Znam(i64 48) #4
4954
%.v = select i1 %b2, i8* %4, i8* %5
@@ -64,6 +69,81 @@ define void @_Z2p2bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
6469
ret void
6570
}
6671

72+
define void @_Z2p4bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
73+
%mStackData = alloca [10 x i32], align 16
74+
%1 = bitcast [10 x i32]* %mStackData to i8*
75+
%2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
76+
%3 = select i1 %b1, i32* %2, i32* @g3
77+
%4 = tail call noalias i8* @_Znam(i64 48) #4
78+
%5 = tail call noalias i8* @_Znam(i64 48) #4
79+
%.v = select i1 %b2, i8* %4, i8* %5
80+
%6 = bitcast i8* %.v to i32*
81+
%7 = icmp eq i32* %6, %3
82+
br i1 %7, label %9, label %8
83+
84+
; CHECK-LABEL: @_Z2p4bb
85+
; CHECK-NOT: icmp
86+
; CHECK: ret void
87+
88+
; <label>:8 ; preds = %0
89+
call void @_ZdaPv(i8* %4) #5
90+
call void @_ZdaPv(i8* %5) #5
91+
br label %9
92+
93+
; <label>:9 ; preds = %0, %8
94+
ret void
95+
}
96+
97+
define void @_Z2p5bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
98+
%mStackData = alloca [10 x i32], align 16
99+
%1 = bitcast [10 x i32]* %mStackData to i8*
100+
%2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
101+
%3 = select i1 %b1, i32* %2, i32* @g4
102+
%4 = tail call noalias i8* @_Znam(i64 48) #4
103+
%5 = tail call noalias i8* @_Znam(i64 48) #4
104+
%.v = select i1 %b2, i8* %4, i8* %5
105+
%6 = bitcast i8* %.v to i32*
106+
%7 = icmp eq i32* %6, %3
107+
br i1 %7, label %9, label %8
108+
109+
; CHECK-LABEL: @_Z2p5bb
110+
; CHECK-NOT: icmp
111+
; CHECK: ret void
112+
113+
; <label>:8 ; preds = %0
114+
call void @_ZdaPv(i8* %4) #5
115+
call void @_ZdaPv(i8* %5) #5
116+
br label %9
117+
118+
; <label>:9 ; preds = %0, %8
119+
ret void
120+
}
121+
122+
define void @_Z2p6bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
123+
%mStackData = alloca [10 x i32], align 16
124+
%1 = bitcast [10 x i32]* %mStackData to i8*
125+
%2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
126+
%3 = select i1 %b1, i32* %2, i32* @g5
127+
%4 = tail call noalias i8* @_Znam(i64 48) #4
128+
%5 = tail call noalias i8* @_Znam(i64 48) #4
129+
%.v = select i1 %b2, i8* %4, i8* %5
130+
%6 = bitcast i8* %.v to i32*
131+
%7 = icmp eq i32* %6, %3
132+
br i1 %7, label %9, label %8
133+
134+
; CHECK-LABEL: @_Z2p6bb
135+
; CHECK-NOT: icmp
136+
; CHECK: ret void
137+
138+
; <label>:8 ; preds = %0
139+
call void @_ZdaPv(i8* %4) #5
140+
call void @_ZdaPv(i8* %5) #5
141+
br label %9
142+
143+
; <label>:9 ; preds = %0, %8
144+
ret void
145+
}
146+
67147
; Here's another case involving multiple underlying objects, but this time we
68148
; must keep the comparison (it might involve a regular pointer-typed function
69149
; argument).
@@ -93,6 +173,77 @@ define void @_Z4nopebbPi(i1 zeroext %b1, i1 zeroext %b2, i32* readnone %q) #0 {
93173
ret void
94174
}
95175

176+
define void @_Z2p3bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
177+
%mStackData = alloca [10 x i32], align 16
178+
%1 = bitcast [10 x i32]* %mStackData to i8*
179+
%2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
180+
%3 = select i1 %b1, i32* %2, i32* @g1
181+
%4 = tail call noalias i8* @_Znam(i64 48) #4
182+
%5 = tail call noalias i8* @_Znam(i64 48) #4
183+
%.v = select i1 %b2, i8* %4, i8* %5
184+
%6 = bitcast i8* %.v to i32*
185+
%7 = icmp eq i32* %6, %3
186+
br i1 %7, label %9, label %8
187+
188+
; CHECK-LABEL: @_Z2p3bb
189+
; CHECK: icmp
190+
; CHECK: ret void
191+
192+
; <label>:8 ; preds = %0
193+
call void @_ZdaPv(i8* %4) #5
194+
call void @_ZdaPv(i8* %5) #5
195+
br label %9
196+
197+
; <label>:9 ; preds = %0, %8
198+
ret void
199+
}
200+
201+
define void @_Z2p7bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
202+
%mStackData = alloca [10 x i32], align 16
203+
%1 = bitcast [10 x i32]* %mStackData to i8*
204+
%2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
205+
%3 = select i1 %b1, i32* %2, i32* @g6
206+
%4 = tail call noalias i8* @_Znam(i64 48) #4
207+
%5 = tail call noalias i8* @_Znam(i64 48) #4
208+
%.v = select i1 %b2, i8* %4, i8* %5
209+
%6 = bitcast i8* %.v to i32*
210+
%7 = icmp eq i32* %6, %3
211+
br i1 %7, label %9, label %8
212+
213+
; CHECK-LABEL: @_Z2p7bb
214+
; CHECK: icmp
215+
; CHECK: ret void
216+
217+
; <label>:8 ; preds = %0
218+
call void @_ZdaPv(i8* %4) #5
219+
call void @_ZdaPv(i8* %5) #5
220+
br label %9
221+
222+
; <label>:9 ; preds = %0, %8
223+
ret void
224+
}
225+
226+
define void @_Z2p2v(i32 %c) #0 {
227+
%mStackData = alloca [10 x i32], i32 %c, align 16
228+
%1 = bitcast [10 x i32]* %mStackData to i8*
229+
%2 = tail call noalias i8* @_Znam(i64 48) #4
230+
%3 = bitcast i8* %2 to i32*
231+
%4 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
232+
%5 = icmp eq i32* %3, %4
233+
br i1 %5, label %7, label %6
234+
235+
; CHECK-LABEL: @_Z2p2v
236+
; CHECK: icmp
237+
; CHECK: ret void
238+
239+
; <label>:6 ; preds = %0
240+
call void @_ZdaPv(i8* %2) #5
241+
br label %7
242+
243+
; <label>:7 ; preds = %0, %6
244+
ret void
245+
}
246+
96247
; Function Attrs: nobuiltin
97248
declare noalias i8* @_Znam(i64) #2
98249

0 commit comments

Comments
 (0)