-
Notifications
You must be signed in to change notification settings - Fork 734
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[AArch64] Add Defs=[NZCV] to MTE loop pseudos.
The `STGloop` family of pseudo-instructions all expand to a loop which iterates over a region of memory setting all its MTE tags to a given value. The loop writes to the flags in order to check termination. But the unexpanded pseudo-instructions were not marked as modifying the flags. Therefore it was possible for one to end up in a location where the flags were live, and then the loop would corrupt them. We spotted the effect of this in a libc++ test involving a lot of complicated inlining, and haven't been able to construct a smaller test case that demonstrates actual incorrect output code. So my test here is just checking that `implicit-def $nzcv` shows up on the pseudo-instructions as they're output from isel. Reviewed By: DavidSpickett Differential Revision: https://reviews.llvm.org/D158262
- Loading branch information
1 parent
7549cde
commit b09c575
Showing
2 changed files
with
60 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
; RUN: llc -O2 -print-after-isel -mtriple=aarch64-linux-gnu %s -o /dev/null 2>&1 | FileCheck %s --check-prefixes=CHECK | ||
|
||
; This test function includes a 256-byte buffer. We expect it to require its | ||
; MTE tags to be set to a useful value on entry, and cleared again on exit. At | ||
; the time of writing this test, the pseudo-instructions chosen are | ||
; STGloop_wback and STGloop respectively, but if different pseudos are selected | ||
; in future, that's not a problem. The important thing is that both should | ||
; include that implicit-def of $nzcv, because these pseudo-instructions will | ||
; expand into loops that use the flags for their termination tests. | ||
|
||
; CHECK: STGloop_wback 256, {{.*}}, implicit-def dead $nzcv | ||
; CHECK: STGloop 256, {{.*}}, implicit-def dead $nzcv | ||
|
||
define i32 @foo(i32 noundef %0) #0 { | ||
%2 = alloca i32, align 4 | ||
%3 = alloca [256 x i8], align 1 | ||
%4 = alloca i64, align 8 | ||
%5 = alloca i32, align 4 | ||
%6 = alloca i64, align 8 | ||
store i32 %0, ptr %2, align 4 | ||
%7 = load i32, ptr %2, align 4 | ||
%8 = getelementptr inbounds [256 x i8], ptr %3, i64 0, i64 0 | ||
%9 = call i64 @read(i32 noundef %7, ptr noundef %8, i64 noundef 256) | ||
store i64 %9, ptr %4, align 8 | ||
store i32 0, ptr %5, align 4 | ||
store i64 0, ptr %6, align 8 | ||
br label %10 | ||
|
||
10: ; preds = %21, %1 | ||
%11 = load i64, ptr %6, align 8 | ||
%12 = load i64, ptr %4, align 8 | ||
%13 = icmp ult i64 %11, %12 | ||
br i1 %13, label %14, label %24 | ||
|
||
14: ; preds = %10 | ||
%15 = load i64, ptr %6, align 8 | ||
%16 = getelementptr inbounds [256 x i8], ptr %3, i64 0, i64 %15 | ||
%17 = load i8, ptr %16, align 1 | ||
%18 = zext i8 %17 to i32 | ||
%19 = load i32, ptr %5, align 4 | ||
%20 = add nsw i32 %19, %18 | ||
store i32 %20, ptr %5, align 4 | ||
br label %21 | ||
|
||
21: ; preds = %14 | ||
%22 = load i64, ptr %6, align 8 | ||
%23 = add i64 %22, 1 | ||
store i64 %23, ptr %6, align 8 | ||
br label %10 | ||
|
||
24: ; preds = %10 | ||
%25 = load i32, ptr %5, align 4 | ||
%26 = srem i32 %25, 251 | ||
ret i32 %26 | ||
} | ||
|
||
declare i64 @read(i32 noundef, ptr noundef, i64 noundef) | ||
|
||
attributes #0 = { sanitize_memtag "target-features"="+mte" } |