summaryrefslogtreecommitdiff
path: root/test/CodeGen/AArch64/flags-multiuse.ll
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen/AArch64/flags-multiuse.ll')
-rw-r--r--test/CodeGen/AArch64/flags-multiuse.ll35
1 files changed, 35 insertions, 0 deletions
diff --git a/test/CodeGen/AArch64/flags-multiuse.ll b/test/CodeGen/AArch64/flags-multiuse.ll
new file mode 100644
index 0000000000..80be052cd9
--- /dev/null
+++ b/test/CodeGen/AArch64/flags-multiuse.ll
@@ -0,0 +1,35 @@
+; RUN: llc -march=aarch64 -verify-machineinstrs < %s | FileCheck %s
+
+; LLVM should be able to cope with multiple uses of the same flag-setting
+; instruction at different points of a routine. Either by rematerializing the
+; compare or by saving and restoring the flag register.
+
+declare void @bar()
+
+@var = global i32 0
+
+define i32 @test_multiflag(i32 %n, i32 %m, i32 %o) {
+; CHECK: test_multiflag:
+
+ %test = icmp ne i32 %n, %m
+; CHECK: cmp [[LHS:w[0-9]+]], [[RHS:w[0-9]+]]
+
+ %val = zext i1 %test to i32
+; CHECK: csinc {{[xw][0-9]+}}, {{xzr|wzr}}, {{xzr|wzr}}, eq
+
+ store i32 %val, i32* @var
+
+ call void @bar()
+; CHECK: bl bar
+
+ ; Currently, the comparison is emitted again. An MSR/MRS pair would also be
+ ; acceptable, but assuming the call preserves NZCV is not.
+ br i1 %test, label %iftrue, label %iffalse
+; CHECK: cmp [[LHS]], [[RHS]]
+; CHECK: b.eq
+
+iftrue:
+ ret i32 42
+iffalse:
+ ret i32 0
+}