[PATCH] D21139: [ARM] MSR instructions implicitly set CPSR

Oliver Stannard via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 8 08:23:51 PDT 2016


olista01 created this revision.
olista01 added reviewers: rengolin, t.p.northover.
olista01 added a subscriber: llvm-commits.
olista01 set the repository for this revision to rL LLVM.
Herald added subscribers: rengolin, aemerson.

The MSR instructions can write to the CPSR, but we did not model this
fact, so we could emit them in the middle of IT blocks, changing the
condition flags for later instructions in the block.

The tests use two calls to llvm.write_register.i32 because it is valid
to use these instructions at the end of an IT block, which if conversion
does do in some cases. With two calls, the first clobbers the flags, so
a branch has to be used to make the second one conditional.

Repository:
  rL LLVM

http://reviews.llvm.org/D21139

Files:
  lib/Target/ARM/ARMInstrInfo.td
  lib/Target/ARM/ARMInstrThumb2.td
  test/CodeGen/ARM/msr-it-block.ll

Index: test/CodeGen/ARM/msr-it-block.ll
===================================================================
--- /dev/null
+++ test/CodeGen/ARM/msr-it-block.ll
@@ -0,0 +1,55 @@
+; RUN: llc < %s -mtriple=thumbv6m-none-eabi | FileCheck %s --check-prefix=V6M --check-prefix=CHECK
+; RUN: llc < %s -mtriple=thumbv7m-none-eabi | FileCheck %s --check-prefix=V7M --check-prefix=CHECK
+; RUN: llc < %s -mtriple=thumbv7a-none-eabi | FileCheck %s --check-prefix=V7A --check-prefix=CHECK
+; RUN: llc < %s -mtriple=armv7a-none-eabi   | FileCheck %s --check-prefix=V7A --check-prefix=CHECK
+
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "armv7a-arm-none-eabi"
+
+define void @test_const(i32 %val) {
+; CHECK-LABEL: test_const:
+entry:
+  %cmp = icmp eq i32 %val, 0
+  br i1 %cmp, label %write_reg, label %exit
+
+write_reg:
+  tail call void @llvm.write_register.i32(metadata !0, i32 0)
+  tail call void @llvm.write_register.i32(metadata !0, i32 0)
+; V6M: msr     apsr, {{r[0-9]+}}
+; V6M: msr     apsr, {{r[0-9]+}}
+; V7M: msr     apsr_nzcvq, {{r[0-9]+}}
+; V7M: msr     apsr_nzcvq, {{r[0-9]+}}
+; V7A: msr     APSR_nzcvqg, {{r[0-9]+}}
+; V7A: msr     APSR_nzcvqg, {{r[0-9]+}}
+  br label %exit
+
+exit:
+  ret void
+}
+
+define void @test_var(i32 %val, i32 %apsr) {
+; CHECK-LABEL: test_var:
+entry:
+  %cmp = icmp eq i32 %val, 0
+  br i1 %cmp, label %write_reg, label %exit
+
+write_reg:
+  tail call void @llvm.write_register.i32(metadata !0, i32 %apsr)
+  tail call void @llvm.write_register.i32(metadata !0, i32 %apsr)
+; V6M: msr     apsr, {{r[0-9]+}}
+; V6M: msr     apsr, {{r[0-9]+}}
+; V7M: msr     apsr_nzcvq, {{r[0-9]+}}
+; V7M: msr     apsr_nzcvq, {{r[0-9]+}}
+; V7A: msr     APSR_nzcvqg, {{r[0-9]+}}
+; V7A: msr     APSR_nzcvqg, {{r[0-9]+}}
+  br label %exit
+
+exit:
+  ret void
+}
+
+
+declare void @llvm.write_register.i32(metadata, i32)
+
+!0 = !{!"apsr"}
Index: lib/Target/ARM/ARMInstrThumb2.td
===================================================================
--- lib/Target/ARM/ARMInstrThumb2.td
+++ lib/Target/ARM/ARMInstrThumb2.td
@@ -4083,6 +4083,7 @@
 // same and the assembly parser has no way to distinguish between them. The mask
 // operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
 // the mask with the fields to be accessed in the special register.
+let Defs = [CPSR] in
 def t2MSR_AR : T2I<(outs), (ins msr_mask:$mask, rGPR:$Rn),
                    NoItinerary, "msr", "\t$mask, $Rn", []>,
                Requires<[IsThumb2,IsNotMClass]> {
@@ -4118,6 +4119,7 @@
 // M class MSR.
 //
 // Move from ARM core register to Special Register
+let Defs = [CPSR] in
 def t2MSR_M : T2I<(outs), (ins msr_mask:$SYSm, rGPR:$Rn),
                   NoItinerary, "msr", "\t$SYSm, $Rn", []>,
               Requires<[IsThumb,IsMClass]> {
Index: lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- lib/Target/ARM/ARMInstrInfo.td
+++ lib/Target/ARM/ARMInstrInfo.td
@@ -5233,6 +5233,7 @@
 // to distinguish between them. The mask operand contains the special register
 // (R Bit) in bit 4 and bits 3-0 contains the mask with the fields to be
 // accessed in the special register.
+let Defs = [CPSR] in
 def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary,
               "msr", "\t$mask, $Rn", []> {
   bits<5> mask;
@@ -5247,6 +5248,7 @@
   let Inst{3-0} = Rn;
 }
 
+let Defs = [CPSR] in
 def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask,  mod_imm:$imm), NoItinerary,
                "msr", "\t$mask, $imm", []> {
   bits<5> mask;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21139.60044.patch
Type: text/x-patch
Size: 3584 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160608/250bd365/attachment.bin>


More information about the llvm-commits mailing list