-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[CodeGenPrepare] Filter out unrecreatable addresses from memory optimization #143566
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
b7f4b17
8d928bc
0c804d3
a5b5b9a
81ddd17
360e261
ccf28b5
85eb67b
5215657
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6099,6 +6099,13 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, | |
| } | ||
|
|
||
| if (!ResultIndex) { | ||
| auto PtrInst = dyn_cast<Instruction>(ResultPtr); | ||
| // Here we know that we have just a pointer without any offsets. If | ||
| // this pointer comes from a different from the current basic block we | ||
| // need to know how to recreate it in another basic block. | ||
| // Currently we don't support recreation of any of instruction. | ||
| if (PtrInst && PtrInst->getParent() != MemoryInst->getParent()) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we can change the predicate to To skip arguments and global pointers. I'm not sure if it is completely correct. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer this condition. We should not modify a memory access instruction with pointer comes from argument or global value directly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. I also added tests for arguments and globals. @weiguozhi you may be interested that we don't reuse addresses in these cases: https://godbolt.org/z/q8fzce4ov |
||
| return Modified; | ||
| SunkAddr = ResultPtr; | ||
| } else { | ||
| if (ResultPtr->getType() != I8PtrTy) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 | ||
| ; RUN: opt -S -p 'require<profile-summary>,codegenprepare' -cgpp-huge-func=0 < %s | FileCheck %s | ||
|
|
||
| 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" | ||
| target triple = "x86_64-grtev4-linux-gnu" | ||
|
|
||
| ; Test a scenario when the address cannot be recreated in the current basic block | ||
|
|
||
| declare ptr @get_ptr(i64) | ||
| define void @addr_from_invoke() personality ptr null { | ||
| ; CHECK-LABEL: define void @addr_from_invoke() personality ptr null { | ||
| ; CHECK-NEXT: [[ENTRY:.*:]] | ||
| ; CHECK-NEXT: [[PTR:%.*]] = invoke ptr @get_ptr(i64 0) | ||
| ; CHECK-NEXT: to label %[[BODY_1:.*]] unwind label %[[EHCLEANUP:.*]] | ||
| ; CHECK: [[EHCLEANUP]]: | ||
| ; CHECK-NEXT: [[PAD:%.*]] = cleanuppad within none [] | ||
| ; CHECK-NEXT: cleanupret from [[PAD]] unwind to caller | ||
| ; CHECK: [[BODY_1]]: | ||
| ; CHECK-NEXT: [[GEP1:%.*]] = bitcast ptr [[PTR]] to ptr | ||
| ; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[GEP1]], align 4 | ||
| ; CHECK-NEXT: [[TMP0:%.*]] = bitcast ptr [[PTR]] to ptr | ||
| ; CHECK-NEXT: [[UNUSED:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4 | ||
| ; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP0]], align 4 | ||
| ; CHECK-NEXT: ret void | ||
| ; | ||
| entry: | ||
| %ptr = invoke ptr @get_ptr(i64 0) to label %body.1 unwind label %ehcleanup | ||
|
|
||
| body.2: | ||
| %unused = load <4 x i32>, ptr %gep, align 4 | ||
| store <4 x i32> zeroinitializer, ptr %gep, align 4 | ||
| ret void | ||
|
|
||
| ehcleanup: | ||
| %pad = cleanuppad within none [] | ||
| cleanupret from %pad unwind to caller | ||
|
|
||
| body.1: | ||
| %gep = getelementptr { i32 }, ptr %ptr, i64 0, i32 0 | ||
| store <4 x i32> zeroinitializer, ptr %gep, align 4 | ||
| br label %body.2 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
different BB