This repository has been archived by the owner on Apr 23, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Preserve nonnull metadata on Loads through SROA & mem2reg.
Summary: https://llvm.org/bugs/show_bug.cgi?id=31142 : SROA was dropping the nonnull metadata on loads from allocas that got optimized out. This patch simply preserves nonnull metadata on loads through SROA and mem2reg. Reviewers: chandlerc, efriedma Reviewed By: efriedma Subscribers: hfinkel, spatel, efriedma, arielb1, davide, llvm-commits Differential Revision: https://reviews.llvm.org/D27114 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298540 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Showing
4 changed files
with
166 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
; RUN: opt < %s -mem2reg -S | FileCheck %s | ||
|
||
; This tests that mem2reg preserves the !nonnull metadata on loads | ||
; from allocas that get optimized out. | ||
|
||
; Check the case where the alloca in question has a single store. | ||
define float* @single_store(float** %arg) { | ||
; CHECK-LABEL: define float* @single_store | ||
; CHECK: %arg.load = load float*, float** %arg, align 8 | ||
; CHECK: [[ASSUME:%(.*)]] = icmp ne float* %arg.load, null | ||
; CHECK: call void @llvm.assume(i1 {{.*}}[[ASSUME]]) | ||
; CHECK: ret float* %arg.load | ||
entry: | ||
%buf = alloca float* | ||
%arg.load = load float*, float** %arg, align 8 | ||
store float* %arg.load, float** %buf, align 8 | ||
%buf.load = load float*, float **%buf, !nonnull !0 | ||
ret float* %buf.load | ||
} | ||
|
||
; Check the case where the alloca in question has more than one | ||
; store but still within one basic block. | ||
define float* @single_block(float** %arg) { | ||
; CHECK-LABEL: define float* @single_block | ||
; CHECK: %arg.load = load float*, float** %arg, align 8 | ||
; CHECK: [[ASSUME:%(.*)]] = icmp ne float* %arg.load, null | ||
; CHECK: call void @llvm.assume(i1 {{.*}}[[ASSUME]]) | ||
; CHECK: ret float* %arg.load | ||
entry: | ||
%buf = alloca float* | ||
%arg.load = load float*, float** %arg, align 8 | ||
store float* null, float** %buf, align 8 | ||
store float* %arg.load, float** %buf, align 8 | ||
%buf.load = load float*, float **%buf, !nonnull !0 | ||
ret float* %buf.load | ||
} | ||
|
||
; Check the case where the alloca in question has more than one | ||
; store and also reads ands writes in multiple blocks. | ||
define float* @multi_block(float** %arg) { | ||
; CHECK-LABEL: define float* @multi_block | ||
; CHECK-LABEL: entry: | ||
; CHECK: %arg.load = load float*, float** %arg, align 8 | ||
; CHECK: br label %next | ||
; CHECK-LABEL: next: | ||
; CHECK: [[ASSUME:%(.*)]] = icmp ne float* %arg.load, null | ||
; CHECK: call void @llvm.assume(i1 {{.*}}[[ASSUME]]) | ||
; CHECK: ret float* %arg.load | ||
entry: | ||
%buf = alloca float* | ||
%arg.load = load float*, float** %arg, align 8 | ||
store float* null, float** %buf, align 8 | ||
br label %next | ||
next: | ||
store float* %arg.load, float** %buf, align 8 | ||
%buf.load = load float*, float** %buf, !nonnull !0 | ||
ret float* %buf.load | ||
} | ||
|
||
; Check that we don't add an assume if it's not | ||
; necessary i.e. the value is already implied to be nonnull | ||
define float* @no_assume(float** %arg) { | ||
; CHECK-LABEL: define float* @no_assume | ||
; CHECK-LABEL: entry: | ||
; CHECK: %arg.load = load float*, float** %arg, align 8 | ||
; CHECK: %cn = icmp ne float* %arg.load, null | ||
; CHECK: br i1 %cn, label %next, label %fin | ||
; CHECK-LABEL: next: | ||
; CHECK-NOT: call void @llvm.assume | ||
; CHECK: ret float* %arg.load | ||
; CHECK-LABEL: fin: | ||
; CHECK: ret float* null | ||
entry: | ||
%buf = alloca float* | ||
%arg.load = load float*, float** %arg, align 8 | ||
%cn = icmp ne float* %arg.load, null | ||
br i1 %cn, label %next, label %fin | ||
next: | ||
; At this point the above nonnull check ensures that | ||
; the value %arg.load is nonnull in this block and thus | ||
; we need not add the assume. | ||
store float* %arg.load, float** %buf, align 8 | ||
%buf.load = load float*, float** %buf, !nonnull !0 | ||
ret float* %buf.load | ||
fin: | ||
ret float* null | ||
} | ||
|
||
!0 = !{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
; RUN: opt < %s -sroa -S | FileCheck %s | ||
; | ||
; Make sure that SROA doesn't lose nonnull metadata | ||
; on loads from allocas that get optimized out. | ||
|
||
; CHECK-LABEL: define float* @yummy_nonnull | ||
; CHECK: [[RETURN:%(.*)]] = load float*, float** %arg, align 8 | ||
; CHECK: [[ASSUME:%(.*)]] = icmp ne float* {{.*}}[[RETURN]], null | ||
; CHECK: call void @llvm.assume(i1 {{.*}}[[ASSUME]]) | ||
; CHECK: ret float* {{.*}}[[RETURN]] | ||
|
||
define float* @yummy_nonnull(float** %arg) { | ||
entry-block: | ||
%buf = alloca float* | ||
|
||
%_arg_i8 = bitcast float** %arg to i8* | ||
%_buf_i8 = bitcast float** %buf to i8* | ||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %_buf_i8, i8* %_arg_i8, i64 8, i32 8, i1 false) | ||
|
||
%ret = load float*, float** %buf, align 8, !nonnull !0 | ||
ret float* %ret | ||
} | ||
|
||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) | ||
|
||
!0 = !{} |