patch-r262261-llvm-r198157-sparc.diff revision 269012
1Pull in r198157 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3  [SparcV9] Use separate instruction patterns for 64 bit arithmetic instructions instead of reusing 32 bit instruction patterns.
4  This is done to avoid spilling the result of the 64-bit instructions to a 4-byte slot.
5
6Introduced here: http://svnweb.freebsd.org/changeset/base/262261
7
8Index: lib/Target/Sparc/SparcAsmPrinter.cpp
9===================================================================
10--- lib/Target/Sparc/SparcAsmPrinter.cpp
11+++ lib/Target/Sparc/SparcAsmPrinter.cpp
12@@ -227,7 +227,7 @@ void SparcAsmPrinter::printOperand(const MachineIn
13     if (MI->getOpcode() == SP::CALL)
14       assert(TF == SPII::MO_NO_FLAG &&
15              "Cannot handle target flags on call address");
16-    else if (MI->getOpcode() == SP::SETHIi)
17+    else if (MI->getOpcode() == SP::SETHIi || MI->getOpcode() == SP::SETHIXi)
18       assert((TF == SPII::MO_HI || TF == SPII::MO_H44 || TF == SPII::MO_HH
19               || TF == SPII::MO_TLS_GD_HI22
20               || TF == SPII::MO_TLS_LDM_HI22
21@@ -250,7 +250,7 @@ void SparcAsmPrinter::printOperand(const MachineIn
22     else if (MI->getOpcode() == SP::TLS_LDXrr)
23       assert(TF == SPII::MO_TLS_IE_LDX &&
24              "Cannot handle target flags on ldx for TLS");
25-    else if (MI->getOpcode() == SP::XORri)
26+    else if (MI->getOpcode() == SP::XORri || MI->getOpcode() == SP::XORXri)
27       assert((TF == SPII::MO_TLS_LDO_LOX10 || TF == SPII::MO_TLS_LE_LOX10) &&
28              "Cannot handle target flags on xor for TLS");
29     else
30Index: lib/Target/Sparc/SparcInstr64Bit.td
31===================================================================
32--- lib/Target/Sparc/SparcInstr64Bit.td
33+++ lib/Target/Sparc/SparcInstr64Bit.td
34@@ -141,32 +141,36 @@ def : Pat<(i64 imm:$val),
35 let Predicates = [Is64Bit] in {
36 
37 // Register-register instructions.
38+defm ANDX    : F3_12<"and", 0b000001, and, I64Regs, i64, i64imm>;
39+defm ORX     : F3_12<"or",  0b000010, or,  I64Regs, i64, i64imm>;
40+defm XORX    : F3_12<"xor", 0b000011, xor, I64Regs, i64, i64imm>;
41 
42-def : Pat<(and i64:$a, i64:$b), (ANDrr $a, $b)>;
43-def : Pat<(or  i64:$a, i64:$b), (ORrr  $a, $b)>;
44-def : Pat<(xor i64:$a, i64:$b), (XORrr $a, $b)>;
45+def ANDXNrr  : F3_1<2, 0b000101,
46+                 (outs I64Regs:$dst), (ins I64Regs:$b, I64Regs:$c),
47+                 "andn $b, $c, $dst",
48+                 [(set i64:$dst, (and i64:$b, (not i64:$c)))]>;
49+def ORXNrr   : F3_1<2, 0b000110,
50+                 (outs I64Regs:$dst), (ins I64Regs:$b, I64Regs:$c),
51+                 "orn $b, $c, $dst",
52+                 [(set i64:$dst, (or i64:$b, (not i64:$c)))]>;
53+def XNORXrr  : F3_1<2, 0b000111,
54+                   (outs I64Regs:$dst), (ins I64Regs:$b, I64Regs:$c),
55+                   "xnor $b, $c, $dst",
56+                   [(set i64:$dst, (not (xor i64:$b, i64:$c)))]>;
57 
58-def : Pat<(and i64:$a, (not i64:$b)), (ANDNrr $a, $b)>;
59-def : Pat<(or  i64:$a, (not i64:$b)), (ORNrr  $a, $b)>;
60-def : Pat<(xor i64:$a, (not i64:$b)), (XNORrr $a, $b)>;
61+defm ADDX    : F3_12<"add", 0b000000, add, I64Regs, i64, i64imm>;
62+defm SUBX    : F3_12<"sub", 0b000100, sub, I64Regs, i64, i64imm>;
63 
64-def : Pat<(add i64:$a, i64:$b), (ADDrr $a, $b)>;
65-def : Pat<(sub i64:$a, i64:$b), (SUBrr $a, $b)>;
66-
67 def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>;
68 
69-def : Pat<(tlsadd i64:$a, i64:$b, tglobaltlsaddr:$sym),
70-          (TLS_ADDrr $a, $b, $sym)>;
71+def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$rd),
72+                   (ins I64Regs:$rs1, I64Regs:$rs2, TLSSym:$sym),
73+                   "add $rs1, $rs2, $rd, $sym",
74+                   [(set i64:$rd,
75+                       (tlsadd i64:$rs1, i64:$rs2, tglobaltlsaddr:$sym))]>;
76 
77 // Register-immediate instructions.
78 
79-def : Pat<(and i64:$a, (i64 simm13:$b)), (ANDri $a, (as_i32imm $b))>;
80-def : Pat<(or  i64:$a, (i64 simm13:$b)), (ORri  $a, (as_i32imm $b))>;
81-def : Pat<(xor i64:$a, (i64 simm13:$b)), (XORri $a, (as_i32imm $b))>;
82-
83-def : Pat<(add i64:$a, (i64 simm13:$b)), (ADDri $a, (as_i32imm $b))>;
84-def : Pat<(sub i64:$a, (i64 simm13:$b)), (SUBri $a, (as_i32imm $b))>;
85-
86 def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>;
87 
88 def : Pat<(ctpop i64:$src), (POPCrr $src)>;
89@@ -402,3 +406,38 @@ def : Pat<(SPselectfcc (i64 simm11:$t), i64:$f, im
90           (MOVFCCri (as_i32imm $t), $f, imm:$cond)>;
91 
92 } // Predicates = [Is64Bit]
93+
94+
95+// 64 bit SETHI
96+let Predicates = [Is64Bit] in {
97+def SETHIXi : F2_1<0b100,
98+                   (outs IntRegs:$rd), (ins i64imm:$imm22),
99+                   "sethi $imm22, $rd",
100+                   [(set i64:$rd, SETHIimm:$imm22)]>;
101+}
102+// Global addresses, constant pool entries
103+let Predicates = [Is64Bit] in {
104+
105+def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>;
106+def : Pat<(SPlo tglobaladdr:$in), (ORXri (i64 G0), tglobaladdr:$in)>;
107+def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>;
108+def : Pat<(SPlo tconstpool:$in), (ORXri (i64 G0), tconstpool:$in)>;
109+
110+// GlobalTLS addresses
111+def : Pat<(SPhi tglobaltlsaddr:$in), (SETHIi tglobaltlsaddr:$in)>;
112+def : Pat<(SPlo tglobaltlsaddr:$in), (ORXri (i64 G0), tglobaltlsaddr:$in)>;
113+def : Pat<(add (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)),
114+          (ADDXri (SETHIXi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>;
115+def : Pat<(xor (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)),
116+          (XORXri  (SETHIXi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>;
117+
118+// Blockaddress
119+def : Pat<(SPhi tblockaddress:$in), (SETHIi tblockaddress:$in)>;
120+def : Pat<(SPlo tblockaddress:$in), (ORXri (i64 G0), tblockaddress:$in)>;
121+
122+// Add reg, lo.  This is used when taking the addr of a global/constpool entry.
123+def : Pat<(add iPTR:$r, (SPlo tglobaladdr:$in)), (ADDXri $r, tglobaladdr:$in)>;
124+def : Pat<(add iPTR:$r, (SPlo tconstpool:$in)),  (ADDXri $r, tconstpool:$in)>;
125+def : Pat<(add iPTR:$r, (SPlo tblockaddress:$in)),
126+                        (ADDXri $r, tblockaddress:$in)>;
127+}
128Index: lib/Target/Sparc/SparcInstrInfo.td
129===================================================================
130--- lib/Target/Sparc/SparcInstrInfo.td
131+++ lib/Target/Sparc/SparcInstrInfo.td
132@@ -210,15 +210,16 @@ def FCC_O   : FCC_VAL<29>;  // Ordered
133 //===----------------------------------------------------------------------===//
134 
135 /// F3_12 multiclass - Define a normal F3_1/F3_2 pattern in one shot.
136-multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode> {
137+multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode,
138+                 RegisterClass RC, ValueType Ty, Operand immOp> {
139   def rr  : F3_1<2, Op3Val,
140-                 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
141+                 (outs RC:$dst), (ins RC:$b, RC:$c),
142                  !strconcat(OpcStr, " $b, $c, $dst"),
143-                 [(set i32:$dst, (OpNode i32:$b, i32:$c))]>;
144+                 [(set Ty:$dst, (OpNode Ty:$b, Ty:$c))]>;
145   def ri  : F3_2<2, Op3Val,
146-                 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
147+                 (outs RC:$dst), (ins RC:$b, immOp:$c),
148                  !strconcat(OpcStr, " $b, $c, $dst"),
149-                 [(set i32:$dst, (OpNode i32:$b, (i32 simm13:$c)))]>;
150+                 [(set Ty:$dst, (OpNode Ty:$b, (Ty simm13:$c)))]>;
151 }
152 
153 /// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no
154@@ -464,7 +465,7 @@ let rd = 0, imm22 = 0 in
155   def NOP : F2_1<0b100, (outs), (ins), "nop", []>;
156 
157 // Section B.11 - Logical Instructions, p. 106
158-defm AND    : F3_12<"and", 0b000001, and>;
159+defm AND    : F3_12<"and", 0b000001, and, IntRegs, i32, i32imm>;
160 
161 def ANDNrr  : F3_1<2, 0b000101,
162                    (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
163@@ -474,7 +475,7 @@ def ANDNri  : F3_2<2, 0b000101,
164                    (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
165                    "andn $b, $c, $dst", []>;
166 
167-defm OR     : F3_12<"or", 0b000010, or>;
168+defm OR     : F3_12<"or", 0b000010, or, IntRegs, i32, i32imm>;
169 
170 def ORNrr   : F3_1<2, 0b000110,
171                    (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
172@@ -483,7 +484,7 @@ def ORNrr   : F3_1<2, 0b000110,
173 def ORNri   : F3_2<2, 0b000110,
174                    (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
175                    "orn $b, $c, $dst", []>;
176-defm XOR    : F3_12<"xor", 0b000011, xor>;
177+defm XOR    : F3_12<"xor", 0b000011, xor, IntRegs, i32, i32imm>;
178 
179 def XNORrr  : F3_1<2, 0b000111,
180                    (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
181@@ -494,12 +495,12 @@ def XNORri  : F3_2<2, 0b000111,
182                    "xnor $b, $c, $dst", []>;
183 
184 // Section B.12 - Shift Instructions, p. 107
185-defm SLL : F3_12<"sll", 0b100101, shl>;
186-defm SRL : F3_12<"srl", 0b100110, srl>;
187-defm SRA : F3_12<"sra", 0b100111, sra>;
188+defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, i32imm>;
189+defm SRL : F3_12<"srl", 0b100110, srl, IntRegs, i32, i32imm>;
190+defm SRA : F3_12<"sra", 0b100111, sra, IntRegs, i32, i32imm>;
191 
192 // Section B.13 - Add Instructions, p. 108
193-defm ADD   : F3_12<"add", 0b000000, add>;
194+defm ADD   : F3_12<"add", 0b000000, add, IntRegs, i32, i32imm>;
195 
196 // "LEA" forms of add (patterns to make tblgen happy)
197 let Predicates = [Is32Bit] in
198@@ -509,18 +510,18 @@ let Predicates = [Is32Bit] in
199                      [(set iPTR:$dst, ADDRri:$addr)]>;
200 
201 let Defs = [ICC] in
202-  defm ADDCC  : F3_12<"addcc", 0b010000, addc>;
203+  defm ADDCC  : F3_12<"addcc", 0b010000, addc, IntRegs, i32, i32imm>;
204 
205 let Uses = [ICC], Defs = [ICC] in
206-  defm ADDX  : F3_12<"addxcc", 0b011000, adde>;
207+  defm ADDE  : F3_12<"addxcc", 0b011000, adde, IntRegs, i32, i32imm>;
208 
209 // Section B.15 - Subtract Instructions, p. 110
210-defm SUB    : F3_12  <"sub"  , 0b000100, sub>;
211+defm SUB    : F3_12  <"sub"  , 0b000100, sub, IntRegs, i32, i32imm>;
212 let Uses = [ICC], Defs = [ICC] in
213-  defm SUBX   : F3_12  <"subxcc" , 0b011100, sube>;
214+  defm SUBE   : F3_12  <"subxcc" , 0b011100, sube, IntRegs, i32, i32imm>;
215 
216 let Defs = [ICC] in
217-  defm SUBCC  : F3_12  <"subcc", 0b010100, subc>;
218+  defm SUBCC  : F3_12  <"subcc", 0b010100, subc, IntRegs, i32, i32imm>;
219 
220 let Defs = [ICC], rd = 0 in {
221   def CMPrr   : F3_1<2, 0b010100,
222@@ -542,7 +543,7 @@ let Uses = [ICC], Defs = [ICC] in
223 // Section B.18 - Multiply Instructions, p. 113
224 let Defs = [Y] in {
225   defm UMUL : F3_12np<"umul", 0b001010>;
226-  defm SMUL : F3_12  <"smul", 0b001011, mul>;
227+  defm SMUL : F3_12  <"smul", 0b001011, mul, IntRegs, i32, i32imm>;
228 }
229 
230 // Section B.19 - Divide Instructions, p. 115
231@@ -987,6 +988,8 @@ def : Pat<(i32 imm:$val),
232 
233 
234 // Global addresses, constant pool entries
235+let Predicates = [Is32Bit] in {
236+
237 def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>;
238 def : Pat<(SPlo tglobaladdr:$in), (ORri (i32 G0), tglobaladdr:$in)>;
239 def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>;
240@@ -1009,6 +1012,7 @@ def : Pat<(add iPTR:$r, (SPlo tglobaladdr:$in)), (
241 def : Pat<(add iPTR:$r, (SPlo tconstpool:$in)),  (ADDri $r, tconstpool:$in)>;
242 def : Pat<(add iPTR:$r, (SPlo tblockaddress:$in)),
243                         (ADDri $r, tblockaddress:$in)>;
244+}
245 
246 // Calls:
247 def : Pat<(call tglobaladdr:$dst),
248Index: test/CodeGen/SPARC/64spill.ll
249===================================================================
250--- test/CodeGen/SPARC/64spill.ll
251+++ test/CodeGen/SPARC/64spill.ll
252@@ -0,0 +1,116 @@
253+; RUN: llc < %s -march=sparcv9 | FileCheck %s
254+
255+target datalayout = "E-i64:64-n32:64-S128"
256+target triple = "sparc64-sun-sparc"
257+
258+; CHECK-LABEL: test_and_spill
259+; CHECK:       and %i0, %i1, [[R:%[gilo][0-7]]]
260+; CHECK:       stx [[R]], [%fp+{{.+}}]
261+; CHECK:       ldx [%fp+{{.+}}, %i0
262+define i64 @test_and_spill(i64 %a, i64 %b) {
263+entry:
264+  %r0 = and i64 %a, %b
265+  %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
266+  ret i64 %r0
267+}
268+
269+; CHECK-LABEL: test_or_spill
270+; CHECK:       or %i0, %i1, [[R:%[gilo][0-7]]]
271+; CHECK:       stx [[R]], [%fp+{{.+}}]
272+; CHECK:       ldx [%fp+{{.+}}, %i0
273+define i64 @test_or_spill(i64 %a, i64 %b) {
274+entry:
275+  %r0 = or i64 %a, %b
276+  %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
277+  ret i64 %r0
278+}
279+
280+; CHECK-LABEL: test_xor_spill
281+; CHECK:       xor %i0, %i1, [[R:%[gilo][0-7]]]
282+; CHECK:       stx [[R]], [%fp+{{.+}}]
283+; CHECK:       ldx [%fp+{{.+}}, %i0
284+define i64 @test_xor_spill(i64 %a, i64 %b) {
285+entry:
286+  %r0 = xor i64 %a, %b
287+  %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
288+  ret i64 %r0
289+}
290+
291+
292+; CHECK-LABEL: test_add_spill
293+; CHECK:       add %i0, %i1, [[R:%[gilo][0-7]]]
294+; CHECK:       stx [[R]], [%fp+{{.+}}]
295+; CHECK:       ldx [%fp+{{.+}}, %i0
296+define i64 @test_add_spill(i64 %a, i64 %b) {
297+entry:
298+  %r0 = add i64 %a, %b
299+  %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
300+  ret i64 %r0
301+}
302+
303+; CHECK-LABEL: test_sub_spill
304+; CHECK:       sub %i0, %i1, [[R:%[gilo][0-7]]]
305+; CHECK:       stx [[R]], [%fp+{{.+}}]
306+; CHECK:       ldx [%fp+{{.+}}, %i0
307+define i64 @test_sub_spill(i64 %a, i64 %b) {
308+entry:
309+  %r0 = sub i64 %a, %b
310+  %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
311+  ret i64 %r0
312+}
313+
314+; CHECK-LABEL: test_andi_spill
315+; CHECK:       and %i0, 1729, [[R:%[gilo][0-7]]]
316+; CHECK:       stx [[R]], [%fp+{{.+}}]
317+; CHECK:       ldx [%fp+{{.+}}, %i0
318+define i64 @test_andi_spill(i64 %a) {
319+entry:
320+  %r0 = and i64 %a, 1729
321+  %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
322+  ret i64 %r0
323+}
324+
325+; CHECK-LABEL: test_ori_spill
326+; CHECK:       or %i0, 1729, [[R:%[gilo][0-7]]]
327+; CHECK:       stx [[R]], [%fp+{{.+}}]
328+; CHECK:       ldx [%fp+{{.+}}, %i0
329+define i64 @test_ori_spill(i64 %a) {
330+entry:
331+  %r0 = or i64 %a, 1729
332+  %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
333+  ret i64 %r0
334+}
335+
336+; CHECK-LABEL: test_xori_spill
337+; CHECK:       xor %i0, 1729, [[R:%[gilo][0-7]]]
338+; CHECK:       stx [[R]], [%fp+{{.+}}]
339+; CHECK:       ldx [%fp+{{.+}}, %i0
340+define i64 @test_xori_spill(i64 %a) {
341+entry:
342+  %r0 = xor i64 %a, 1729
343+  %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
344+  ret i64 %r0
345+}
346+
347+; CHECK-LABEL: test_addi_spill
348+; CHECK:       add %i0, 1729, [[R:%[gilo][0-7]]]
349+; CHECK:       stx [[R]], [%fp+{{.+}}]
350+; CHECK:       ldx [%fp+{{.+}}, %i0
351+define i64 @test_addi_spill(i64 %a) {
352+entry:
353+  %r0 = add i64 %a, 1729
354+  %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
355+  ret i64 %r0
356+}
357+
358+; CHECK-LABEL: test_subi_spill
359+; CHECK:       add %i0, -1729, [[R:%[gilo][0-7]]]
360+; CHECK:       stx [[R]], [%fp+{{.+}}]
361+; CHECK:       ldx [%fp+{{.+}}, %i0
362+define i64 @test_subi_spill(i64 %a) {
363+entry:
364+  %r0 = sub i64 %a, 1729
365+  %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
366+  ret i64 %r0
367+}
368+
369