Skip to content

Commit 5ffdd94

Browse files
authored
[CodeGenPrepare] Filter out unrecreatable addresses from memory optimization (#143566)
Follow up on #139303
1 parent 3ea7fc7 commit 5ffdd94

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6092,6 +6092,13 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
60926092
}
60936093

60946094
if (!ResultIndex) {
6095+
auto PtrInst = dyn_cast<Instruction>(ResultPtr);
6096+
// We know that we have a pointer without any offsets. If this pointer
6097+
// originates from a different basic block than the current one, we
6098+
// must be able to recreate it in the current basic block.
6099+
// We do not support the recreation of any instructions yet.
6100+
if (PtrInst && PtrInst->getParent() != MemoryInst->getParent())
6101+
return Modified;
60956102
SunkAddr = ResultPtr;
60966103
} else {
60976104
if (ResultPtr->getType() != I8PtrTy)
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -p 'require<profile-summary>,codegenprepare' -cgpp-huge-func=0 < %s | FileCheck %s
3+
4+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
5+
target triple = "x86_64-grtev4-linux-gnu"
6+
7+
@globalptr = external global ptr
8+
declare ptr @get_ptr(i64)
9+
10+
; Can't recreate invoke instruction
11+
12+
define void @addr_from_invoke() personality ptr null {
13+
; CHECK-LABEL: define void @addr_from_invoke() personality ptr null {
14+
; CHECK-NEXT: [[ENTRY:.*:]]
15+
; CHECK-NEXT: [[PTR:%.*]] = invoke ptr @get_ptr(i64 0)
16+
; CHECK-NEXT: to label %[[BODY_1:.*]] unwind label %[[EHCLEANUP:.*]]
17+
; CHECK: [[EHCLEANUP]]:
18+
; CHECK-NEXT: [[PAD:%.*]] = cleanuppad within none []
19+
; CHECK-NEXT: cleanupret from [[PAD]] unwind to caller
20+
; CHECK: [[BODY_1]]:
21+
; CHECK-NEXT: [[GEP1:%.*]] = bitcast ptr [[PTR]] to ptr
22+
; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[GEP1]], align 4
23+
; CHECK-NEXT: [[TMP0:%.*]] = bitcast ptr [[PTR]] to ptr
24+
; CHECK-NEXT: [[UNUSED:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
25+
; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP0]], align 4
26+
; CHECK-NEXT: ret void
27+
;
28+
entry:
29+
%ptr = invoke ptr @get_ptr(i64 0) to label %body.1 unwind label %ehcleanup
30+
31+
body.2:
32+
%unused = load <4 x i32>, ptr %gep, align 4
33+
store <4 x i32> zeroinitializer, ptr %gep, align 4
34+
ret void
35+
36+
ehcleanup:
37+
%pad = cleanuppad within none []
38+
cleanupret from %pad unwind to caller
39+
40+
body.1:
41+
%gep = getelementptr { i32 }, ptr %ptr, i64 0, i32 0
42+
store <4 x i32> zeroinitializer, ptr %gep, align 4
43+
br label %body.2
44+
}
45+
46+
define void @addr_from_arg(ptr %ptr, i1 %p) {
47+
; CHECK-LABEL: define void @addr_from_arg(
48+
; CHECK-SAME: ptr [[PTR:%.*]], i1 [[P:%.*]]) {
49+
; CHECK-NEXT: [[ENTRY:.*:]]
50+
; CHECK-NEXT: br i1 [[P]], label %[[BODY_1:.*]], label %[[EXIT:.*]]
51+
; CHECK: [[EXIT]]:
52+
; CHECK-NEXT: ret void
53+
; CHECK: [[BODY_1]]:
54+
; CHECK-NEXT: [[TMP0:%.*]] = bitcast ptr [[PTR]] to ptr
55+
; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP0]], align 4
56+
; CHECK-NEXT: [[UNUSED:%.*]] = load <4 x i32>, ptr [[PTR]], align 4
57+
; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[PTR]], align 4
58+
; CHECK-NEXT: ret void
59+
;
60+
entry:
61+
br i1 %p, label %body.1, label %exit
62+
63+
body.2:
64+
%unused = load <4 x i32>, ptr %gep, align 4
65+
store <4 x i32> zeroinitializer, ptr %gep, align 4
66+
ret void
67+
68+
exit:
69+
ret void
70+
71+
body.1:
72+
%gep = getelementptr { i32 }, ptr %ptr, i64 0, i32 0
73+
store <4 x i32> zeroinitializer, ptr %gep, align 4
74+
br label %body.2
75+
}
76+
77+
define void @addr_from_global(i1 %p) {
78+
; CHECK-LABEL: define void @addr_from_global(
79+
; CHECK-SAME: i1 [[P:%.*]]) {
80+
; CHECK-NEXT: [[ENTRY:.*:]]
81+
; CHECK-NEXT: br i1 [[P]], label %[[BODY_1:.*]], label %[[EXIT:.*]]
82+
; CHECK: [[EXIT]]:
83+
; CHECK-NEXT: ret void
84+
; CHECK: [[BODY_1]]:
85+
; CHECK-NEXT: [[GEP1:%.*]] = bitcast ptr @globalptr to ptr
86+
; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[GEP1]], align 4
87+
; CHECK-NEXT: [[UNUSED:%.*]] = load <4 x i32>, ptr @globalptr, align 4
88+
; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr @globalptr, align 4
89+
; CHECK-NEXT: ret void
90+
;
91+
entry:
92+
br i1 %p, label %body.1, label %exit
93+
94+
body.2:
95+
%unused = load <4 x i32>, ptr %gep, align 4
96+
store <4 x i32> zeroinitializer, ptr %gep, align 4
97+
ret void
98+
99+
exit:
100+
ret void
101+
102+
body.1:
103+
%gep = getelementptr { i32 }, ptr @globalptr, i64 0, i32 0
104+
store <4 x i32> zeroinitializer, ptr %gep, align 4
105+
br label %body.2
106+
}

0 commit comments

Comments
 (0)