[llvm-bugs] [Bug 40365] New: InstCombine incorrectly sinks dynamic allocas into a stacksave / stackrestore region
via llvm-bugs
llvm-bugs at lists.llvm.org
Thu Jan 17 11:14:40 PST 2019
https://bugs.llvm.org/show_bug.cgi?id=40365
Bug ID: 40365
Summary: InstCombine incorrectly sinks dynamic allocas into a
stacksave / stackrestore region
Product: libraries
Version: trunk
Hardware: PC
OS: Windows NT
Status: NEW
Severity: enhancement
Priority: P
Component: Scalar Optimizations
Assignee: unassignedbugs at nondot.org
Reporter: rnk at google.com
CC: llvm-bugs at lists.llvm.org
This was originally found at https://crbug.com/922654
Instcombine makes this incorrect transformation:
$ opt -instcombine sink-inalloca.ll -S -o t2.ll
$ diff -U999 sink-inalloca.ll t2.ll
--- sink-inalloca.ll 2019-01-17 11:00:26.186621700 -0800
+++ t2.ll 2019-01-17 11:00:33.390299200 -0800
@@ -1,36 +1,36 @@
-; ModuleID = 'sink-inalloca.bc'
+; ModuleID = 'sink-inalloca.ll'
source_filename = "sink-inalloca.ll"
declare i32* @identity(i32*)
declare i1 @cond()
; Function Attrs: nounwind
declare i8* @llvm.stacksave() #0
; Function Attrs: nounwind
declare void @llvm.stackrestore(i8*) #0
define void @foo(i32 %x) {
entry:
%c1 = call i1 @cond()
br i1 %c1, label %ret, label %nonentry
nonentry: ; preds = %entry
- %argmem = alloca inalloca i32
%sp = call i8* @llvm.stacksave()
%c2 = call i1 @cond()
br i1 %c2, label %ret, label %sinktarget
sinktarget: ; preds = %nonentry
- %p = call i32* @identity(i32* %argmem)
- store i32 13, i32* %p
+ %argmem = alloca inalloca i32, align 4
+ %p = call i32* @identity(i32* nonnull %argmem)
+ store i32 13, i32* %p, align 4
call void @llvm.stackrestore(i8* %sp)
%0 = call i32* @identity(i32* %p)
br label %ret
ret: ; preds = %sinktarget,
%nonentry, %entry
ret void
}
attributes #0 = { nounwind }
Here's a plain C version of the test case that doesn't involve inalloca:
#include <stdbool.h>
bool cond(void);
int *use(void *);
void foo(int n) {
// need p to not be in entry block.
if (cond()) {
void *p = alloca(n);
{
int vla[n];
if (cond())
return;
p = use(p);
use(&vla[0]);
if (cond())
return;
}
use(p);
}
}
inalloca just makes this situation much more common.
Unfortunately, we ran into this after fixing https://llvm.org/pr40118, which
prevented LLVM from optimizing away inalloca after inlining. Treating
"stackrestore" as something that can write anything into memory was a major
pessimization. Previously GVN would eliminate these stores, and the alloca
would become dead, and the stack save and stackrestore would be eliminated.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190117/08a7afc9/attachment.html>
More information about the llvm-bugs
mailing list