]> granicus.if.org Git - llvm/commitdiff
[ARM] Mark LEApcrel instructions as isAsCheapAsAMove
authorJohn Brawn <john.brawn@arm.com>
Mon, 15 May 2017 11:57:54 +0000 (11:57 +0000)
committerJohn Brawn <john.brawn@arm.com>
Mon, 15 May 2017 11:57:54 +0000 (11:57 +0000)
Doing this means that if an LEApcrel is used in two places we will rematerialize
instead of generating two MOVs. This is particularly useful for printfs using
the same format string, where we want to generate an address into a register
that's going to get corrupted by the call.

Differential Revision: https://reviews.llvm.org/D32858

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303054 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb.td
lib/Target/ARM/ARMInstrThumb2.td
test/CodeGen/ARM/adr-remat.ll [new file with mode: 0644]
test/CodeGen/ARM/align-sp-adjustment.ll

index 9e33f5ced87589849cea09c5c220696c8684ea24..5b7666af876350855d4630671c898ac01714ab94 100644 (file)
@@ -2222,7 +2222,7 @@ def ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label),
   let Inst{11-0} = label{11-0};
 }
 
-let hasSideEffects = 0, isReMaterializable = 1 in
+let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in
 def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
                     4, IIC_iALUi, []>, Sched<[WriteALU, ReadALU]>;
 
index bee83dfb6f6361c08c72fed99f09ad4be3f026a2..118627fd5d7cfd44ae684d80f123d4cc27de670c 100644 (file)
@@ -1402,7 +1402,7 @@ def tADR : T1I<(outs tGPR:$Rd), (ins t_adrlabel:$addr, pred:$p),
   let DecoderMethod = "DecodeThumbAddSpecialReg";
 }
 
-let hasSideEffects = 0, isReMaterializable = 1 in
+let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in
 def tLEApcrel   : tPseudoInst<(outs tGPR:$Rd), (ins i32imm:$label, pred:$p),
                               2, IIC_iALUi, []>, Sched<[WriteALU]>;
 
index bf3d820e7b7d0d6922cc5232a6fdd63ffd2198ee..842c46cc2b6c06e2592b2c02ea199153010de389 100644 (file)
@@ -1227,7 +1227,7 @@ def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd),
   let DecoderMethod = "DecodeT2Adr";
 }
 
-let hasSideEffects = 0, isReMaterializable = 1 in
+let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in
 def t2LEApcrel   : t2PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p),
                                 4, IIC_iALUi, []>, Sched<[WriteALU, ReadALU]>;
 let hasSideEffects = 1 in
diff --git a/test/CodeGen/ARM/adr-remat.ll b/test/CodeGen/ARM/adr-remat.ll
new file mode 100644 (file)
index 0000000..15d7f9c
--- /dev/null
@@ -0,0 +1,25 @@
+; RUN: llc -mtriple=armv7a   %s -o - | FileCheck %s
+; RUN: llc -mtriple=thumbv7m %s -o - | FileCheck %s
+; RUN: llc -mtriple=thumbv6m %s -o - | FileCheck %s
+
+@str.1 = private unnamed_addr constant [58 x i8] c"+-------------------------------------------------------+\00"
+@str.2 = private unnamed_addr constant [58 x i8] c"|                                                       |\00"
+
+declare i32 @puts(i8* nocapture readonly)
+
+; Check that we rematerialize the adr of str.1 instead of doing one adr and two
+; movs.
+
+; CHECK: adr r0, [[STR1:.LCPI[0-9]+_[0-9]+]]
+; CHECK: bl puts
+; CHECK: adr r0, {{.LCPI[0-9]+_[0-9]+}}
+; CHECK: bl puts
+; CHECK: adr r0, [[STR1]]
+; CHECK: b{{l?}} puts
+define void @fn() {
+entry:
+  %puts1 = tail call i32 @puts(i8* getelementptr inbounds ([58 x i8], [58 x i8]* @str.1, i32 0, i32 0))
+  %puts2 = tail call i32 @puts(i8* getelementptr inbounds ([58 x i8], [58 x i8]* @str.2, i32 0, i32 0))
+  %puts3 = tail call i32 @puts(i8* getelementptr inbounds ([58 x i8], [58 x i8]* @str.1, i32 0, i32 0))
+  ret void
+}
index cce7b03e2362ac63f316b8ecd0bc791027a4092e..091279e75a25fa512078275b70a8e267c057770d 100644 (file)
@@ -1,6 +1,10 @@
 ; RUN: llc -mtriple=thumbv7 -o - %s | FileCheck %s
 
-; CHECK: [sp, #2120]
+; p5 will have been pushed to the stack. Check that it's correctly aligned by
+; looking at the offset of the instruction that loads it. Note that this is
+; very fragile and this test may need to be updated if we happen to spill more
+; or less to the stack.
+; CHECK: ldr{{(.w)?}} r{{[0-9]+}}, [sp, #2104]
 
 %struct.struct_2 = type { [172 x %struct.struct_1] }
 %struct.struct_1 = type { i32, i32, i32 }