1Pull in r198910 from upstream llvm trunk (by Venkatraman Govindaraju): 2 3 [Sparc] Emit retl/ret instead of jmp instruction. It improves the readability of the assembly generated. 4 5Introduced here: http://svnweb.freebsd.org/changeset/base/262261 6 7Index: test/CodeGen/SPARC/ctpop.ll 8=================================================================== 9--- test/CodeGen/SPARC/ctpop.ll 10+++ test/CodeGen/SPARC/ctpop.ll 11@@ -9,12 +9,12 @@ declare i32 @llvm.ctpop.i32(i32) 12 13 ; V9-LABEL: test 14 ; V9: srl %o0, 0, %o0 15-; V9-NEXT: jmp %o7+8 16+; V9-NEXT: retl 17 ; V9-NEXT: popc %o0, %o0 18 19 ; SPARC64-LABEL: test 20 ; SPARC64: srl %o0, 0, %o0 21-; SPARC64: jmp %o7+8 22+; SPARC64: retl 23 ; SPARC64: popc %o0, %o0 24 25 define i32 @test(i32 %X) { 26Index: test/CodeGen/SPARC/2011-01-11-Call.ll 27=================================================================== 28--- test/CodeGen/SPARC/2011-01-11-Call.ll 29+++ test/CodeGen/SPARC/2011-01-11-Call.ll 30@@ -8,7 +8,7 @@ 31 ; V8-NEXT: nop 32 ; V8: call bar 33 ; V8-NEXT: nop 34-; V8: jmp %i7+8 35+; V8: ret 36 ; V8-NEXT: restore 37 38 ; V9-LABEL: test 39@@ -17,7 +17,7 @@ 40 ; V9-NEXT: nop 41 ; V9: call bar 42 ; V9-NEXT: nop 43-; V9: jmp %i7+8 44+; V9: ret 45 ; V9-NEXT: restore 46 47 define void @test() nounwind { 48@@ -36,7 +36,7 @@ declare void @bar(...) 49 ; V8: save %sp 50 ; V8: call foo 51 ; V8-NEXT: nop 52-; V8: jmp %i7+8 53+; V8: ret 54 ; V8-NEXT: restore %g0, %o0, %o0 55 56 ; V9-LABEL: test_tail_call_with_return 57@@ -43,7 +43,7 @@ declare void @bar(...) 58 ; V9: save %sp 59 ; V9: call foo 60 ; V9-NEXT: nop 61-; V9: jmp %i7+8 62+; V9: ret 63 ; V9-NEXT: restore %g0, %o0, %o0 64 65 define i32 @test_tail_call_with_return() nounwind { 66Index: test/CodeGen/SPARC/leafproc.ll 67=================================================================== 68--- test/CodeGen/SPARC/leafproc.ll 69+++ test/CodeGen/SPARC/leafproc.ll 70@@ -1,7 +1,7 @@ 71 ; RUN: llc -march=sparc -disable-sparc-leaf-proc=0 < %s | FileCheck %s 72 73 ; CHECK-LABEL: func_nobody: 74-; CHECK: jmp %o7+8 75+; CHECK: retl 76 ; CHECK-NEXT: nop 77 define void @func_nobody() { 78 entry: 79@@ -10,7 +10,7 @@ entry: 80 81 82 ; CHECK-LABEL: return_int_const: 83-; CHECK: jmp %o7+8 84+; CHECK: retl 85 ; CHECK-NEXT: or %g0, 1729, %o0 86 define i32 @return_int_const() { 87 entry: 88@@ -19,7 +19,7 @@ entry: 89 90 ; CHECK-LABEL: return_double_const: 91 ; CHECK: sethi 92-; CHECK: jmp %o7+8 93+; CHECK: retl 94 ; CHECK-NEXT: ldd {{.*}}, %f0 95 96 define double @return_double_const() { 97@@ -29,7 +29,7 @@ entry: 98 99 ; CHECK-LABEL: leaf_proc_with_args: 100 ; CHECK: add {{%o[0-1]}}, {{%o[0-1]}}, [[R:%[go][0-7]]] 101-; CHECK: jmp %o7+8 102+; CHECK: retl 103 ; CHECK-NEXT: add [[R]], %o2, %o0 104 105 define i32 @leaf_proc_with_args(i32 %a, i32 %b, i32 %c) { 106@@ -42,7 +42,7 @@ entry: 107 ; CHECK-LABEL: leaf_proc_with_args_in_stack: 108 ; CHECK-DAG: ld [%sp+92], {{%[go][0-7]}} 109 ; CHECK-DAG: ld [%sp+96], {{%[go][0-7]}} 110-; CHECK: jmp %o7+8 111+; CHECK: retl 112 ; CHECK-NEXT: add {{.*}}, %o0 113 define i32 @leaf_proc_with_args_in_stack(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) { 114 entry: 115@@ -63,7 +63,7 @@ entry: 116 ; CHECK: or %g0, 2, [[R2:%[go][0-7]]] 117 ; CHECK: st [[R2]], [%sp+100] 118 ; CHECK: ld {{.+}}, %o0 119-; CHECK: jmp %o7+8 120+; CHECK: retl 121 ; CHECK-NEXT: add %sp, 104, %sp 122 123 define i32 @leaf_proc_with_local_array(i32 %a, i32 %b, i32 %c) { 124Index: test/CodeGen/SPARC/fp128.ll 125=================================================================== 126--- test/CodeGen/SPARC/fp128.ll 127+++ test/CodeGen/SPARC/fp128.ll 128@@ -45,7 +45,7 @@ entry: 129 ; HARD: std %f{{.+}}, [%[[S1:.+]]] 130 ; HARD-DAG: ldd [%[[S0]]], %f{{.+}} 131 ; HARD-DAG: ldd [%[[S1]]], %f{{.+}} 132-; HARD: jmp 133+; HARD: jmp %o7+12 134 135 ; SOFT-LABEL: f128_spill 136 ; SOFT: std %f{{.+}}, [%[[S0:.+]]] 137@@ -52,7 +52,7 @@ entry: 138 ; SOFT: std %f{{.+}}, [%[[S1:.+]]] 139 ; SOFT-DAG: ldd [%[[S0]]], %f{{.+}} 140 ; SOFT-DAG: ldd [%[[S1]]], %f{{.+}} 141-; SOFT: jmp 142+; SOFT: jmp %o7+12 143 144 define void @f128_spill(fp128* noalias sret %scalar.result, fp128* byval %a) { 145 entry: 146@@ -132,13 +132,13 @@ entry: 147 ; HARD: ldub 148 ; HARD: faddq 149 ; HARD: stb 150-; HARD: jmp 151+; HARD: ret 152 153 ; SOFT-LABEL: fp128_unaligned 154 ; SOFT: ldub 155 ; SOFT: call _Q_add 156 ; SOFT: stb 157-; SOFT: jmp 158+; SOFT: ret 159 160 define void @fp128_unaligned(fp128* %a, fp128* %b, fp128* %c) { 161 entry: 162Index: test/CodeGen/SPARC/2011-01-11-FrameAddr.ll 163=================================================================== 164--- test/CodeGen/SPARC/2011-01-11-FrameAddr.ll 165+++ test/CodeGen/SPARC/2011-01-11-FrameAddr.ll 166@@ -9,18 +9,18 @@ define i8* @frameaddr() nounwind readnone { 167 entry: 168 ;V8-LABEL: frameaddr: 169 ;V8: save %sp, -96, %sp 170-;V8: jmp %i7+8 171+;V8: ret 172 ;V8: restore %g0, %fp, %o0 173 174 ;V9-LABEL: frameaddr: 175 ;V9: save %sp, -96, %sp 176-;V9: jmp %i7+8 177+;V9: ret 178 ;V9: restore %g0, %fp, %o0 179 180 ;SPARC64-LABEL: frameaddr 181 ;SPARC64: save %sp, -128, %sp 182 ;SPARC64: add %fp, 2047, %i0 183-;SPARC64: jmp %i7+8 184+;SPARC64: ret 185 ;SPARC64: restore %g0, %g0, %g0 186 187 %0 = tail call i8* @llvm.frameaddress(i32 0) 188Index: test/CodeGen/SPARC/constpool.ll 189=================================================================== 190--- test/CodeGen/SPARC/constpool.ll 191+++ test/CodeGen/SPARC/constpool.ll 192@@ -12,7 +12,7 @@ entry: 193 194 ; abs32: floatCP 195 ; abs32: sethi %hi(.LCPI0_0), %[[R:[gilo][0-7]]] 196-; abs32: jmp %o7+8 197+; abs32: retl 198 ; abs32: ld [%[[R]]+%lo(.LCPI0_0)], %f 199 200 201@@ -20,7 +20,7 @@ entry: 202 ; abs44: sethi %h44(.LCPI0_0), %[[R1:[gilo][0-7]]] 203 ; abs44: add %[[R1]], %m44(.LCPI0_0), %[[R2:[gilo][0-7]]] 204 ; abs44: sllx %[[R2]], 12, %[[R3:[gilo][0-7]]] 205-; abs44: jmp %o7+8 206+; abs44: retl 207 ; abs44: ld [%[[R3]]+%l44(.LCPI0_0)], %f1 208 209 210@@ -30,7 +30,7 @@ entry: 211 ; abs64: sethi %hh(.LCPI0_0), %[[R3:[gilo][0-7]]] 212 ; abs64: add %[[R3]], %hm(.LCPI0_0), %[[R4:[gilo][0-7]]] 213 ; abs64: sllx %[[R4]], 32, %[[R5:[gilo][0-7]]] 214-; abs64: jmp %o7+8 215+; abs64: retl 216 ; abs64: ld [%[[R5]]+%[[R2]]], %f1 217 218 219@@ -40,7 +40,7 @@ entry: 220 ; v8pic32: add %[[R1]], %lo(.LCPI0_0), %[[Goffs:[gilo][0-7]]] 221 ; v8pic32: ld [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]] 222 ; v8pic32: ld [%[[Gaddr]]], %f0 223-; v8pic32: jmp %i7+8 224+; v8pic32: ret 225 ; v8pic32: restore 226 227 228@@ -51,7 +51,7 @@ entry: 229 ; v9pic32: add %[[R1]], %lo(.LCPI0_0), %[[Goffs:[gilo][0-7]]] 230 ; v9pic32: ldx [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]] 231 ; v9pic32: ld [%[[Gaddr]]], %f1 232-; v9pic32: jmp %i7+8 233+; v9pic32: ret 234 ; v9pic32: restore 235 236 237Index: test/CodeGen/SPARC/globals.ll 238=================================================================== 239--- test/CodeGen/SPARC/globals.ll 240+++ test/CodeGen/SPARC/globals.ll 241@@ -14,7 +14,7 @@ define zeroext i8 @loadG() { 242 243 ; abs32: loadG 244 ; abs32: sethi %hi(G), %[[R:[gilo][0-7]]] 245-; abs32: jmp %o7+8 246+; abs32: retl 247 ; abs32: ldub [%[[R]]+%lo(G)], %o0 248 249 250@@ -22,7 +22,7 @@ define zeroext i8 @loadG() { 251 ; abs44: sethi %h44(G), %[[R1:[gilo][0-7]]] 252 ; abs44: add %[[R1]], %m44(G), %[[R2:[gilo][0-7]]] 253 ; abs44: sllx %[[R2]], 12, %[[R3:[gilo][0-7]]] 254-; abs44: jmp %o7+8 255+; abs44: retl 256 ; abs44: ldub [%[[R3]]+%l44(G)], %o0 257 258 259@@ -32,7 +32,7 @@ define zeroext i8 @loadG() { 260 ; abs64: sethi %hh(G), %[[R3:[gilo][0-7]]] 261 ; abs64: add %[[R3]], %hm(G), %[[R4:[gilo][0-7]]] 262 ; abs64: sllx %[[R4]], 32, %[[R5:[gilo][0-7]]] 263-; abs64: jmp %o7+8 264+; abs64: retl 265 ; abs64: ldub [%[[R5]]+%[[R2]]], %o0 266 267 268@@ -42,7 +42,7 @@ define zeroext i8 @loadG() { 269 ; v8pic32: add %[[R1]], %lo(G), %[[Goffs:[gilo][0-7]]] 270 ; v8pic32: ld [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]] 271 ; v8pic32: ldub [%[[Gaddr]]], %i0 272-; v8pic32: jmp %i7+8 273+; v8pic32: ret 274 ; v8pic32: restore 275 276 277@@ -52,6 +52,6 @@ define zeroext i8 @loadG() { 278 ; v9pic32: add %[[R1]], %lo(G), %[[Goffs:[gilo][0-7]]] 279 ; v9pic32: ldx [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]] 280 ; v9pic32: ldub [%[[Gaddr]]], %i0 281-; v9pic32: jmp %i7+8 282+; v9pic32: ret 283 ; v9pic32: restore 284 285Index: test/CodeGen/SPARC/rem.ll 286=================================================================== 287--- test/CodeGen/SPARC/rem.ll 288+++ test/CodeGen/SPARC/rem.ll 289@@ -3,7 +3,7 @@ 290 ; CHECK-LABEL: test1: 291 ; CHECK: sdivx %o0, %o1, %o2 292 ; CHECK-NEXT: mulx %o2, %o1, %o1 293-; CHECK-NEXT: jmp %o7+8 294+; CHECK-NEXT: retl 295 ; CHECK-NEXT: sub %o0, %o1, %o0 296 297 define i64 @test1(i64 %X, i64 %Y) { 298@@ -14,7 +14,7 @@ define i64 @test1(i64 %X, i64 %Y) { 299 ; CHECK-LABEL: test2: 300 ; CHECK: udivx %o0, %o1, %o2 301 ; CHECK-NEXT: mulx %o2, %o1, %o1 302-; CHECK-NEXT: jmp %o7+8 303+; CHECK-NEXT: retl 304 ; CHECK-NEXT: sub %o0, %o1, %o0 305 306 define i64 @test2(i64 %X, i64 %Y) { 307Index: test/CodeGen/SPARC/2011-01-19-DelaySlot.ll 308=================================================================== 309--- test/CodeGen/SPARC/2011-01-19-DelaySlot.ll 310+++ test/CodeGen/SPARC/2011-01-19-DelaySlot.ll 311@@ -7,7 +7,7 @@ entry: 312 ; CHECK: test 313 ; CHECK: call bar 314 ; CHECK-NOT: nop 315-; CHECK: jmp 316+; CHECK: ret 317 ; CHECK-NEXT: restore 318 %0 = tail call i32 @bar(i32 %a) nounwind 319 ret i32 %0 320@@ -18,7 +18,7 @@ entry: 321 ; CHECK: test_jmpl 322 ; CHECK: call 323 ; CHECK-NOT: nop 324-; CHECK: jmp 325+; CHECK: ret 326 ; CHECK-NEXT: restore 327 %0 = tail call i32 %f(i32 %a, i32 %b) nounwind 328 ret i32 %0 329@@ -47,7 +47,7 @@ bb: 330 331 bb5: ; preds = %bb, %entry 332 %a_addr.1.lcssa = phi i32 [ %a, %entry ], [ %a_addr.0, %bb ] 333-;CHECK: jmp 334+;CHECK: retl 335 ;CHECK-NOT: restore 336 ret i32 %a_addr.1.lcssa 337 } 338@@ -110,7 +110,7 @@ declare i32 @func(i32*) 339 define i32 @restore_add(i32 %a, i32 %b) { 340 entry: 341 ;CHECK-LABEL: restore_add: 342-;CHECK: jmp %i7+8 343+;CHECK: ret 344 ;CHECK: restore %o0, %i1, %o0 345 %0 = tail call i32 @bar(i32 %a) nounwind 346 %1 = add nsw i32 %0, %b 347@@ -120,7 +120,7 @@ entry: 348 define i32 @restore_add_imm(i32 %a) { 349 entry: 350 ;CHECK-LABEL: restore_add_imm: 351-;CHECK: jmp %i7+8 352+;CHECK: ret 353 ;CHECK: restore %o0, 20, %o0 354 %0 = tail call i32 @bar(i32 %a) nounwind 355 %1 = add nsw i32 %0, 20 356@@ -130,7 +130,7 @@ entry: 357 define i32 @restore_or(i32 %a) { 358 entry: 359 ;CHECK-LABEL: restore_or: 360-;CHECK: jmp %i7+8 361+;CHECK: ret 362 ;CHECK: restore %g0, %o0, %o0 363 %0 = tail call i32 @bar(i32 %a) nounwind 364 ret i32 %0 365@@ -140,7 +140,7 @@ define i32 @restore_or_imm(i32 %a) { 366 entry: 367 ;CHECK-LABEL: restore_or_imm: 368 ;CHECK: or %o0, 20, %i0 369-;CHECK: jmp %i7+8 370+;CHECK: ret 371 ;CHECK: restore %g0, %g0, %g0 372 %0 = tail call i32 @bar(i32 %a) nounwind 373 %1 = or i32 %0, 20 374Index: test/CodeGen/SPARC/64bit.ll 375=================================================================== 376--- test/CodeGen/SPARC/64bit.ll 377+++ test/CodeGen/SPARC/64bit.ll 378@@ -5,7 +5,7 @@ 379 ; CHECK: or %g0, %i1, %i0 380 381 ; OPT-LABEL: ret2: 382-; OPT: jmp %o7+8 383+; OPT: retl 384 ; OPT: or %g0, %o1, %o0 385 define i64 @ret2(i64 %a, i64 %b) { 386 ret i64 %b 387@@ -15,7 +15,7 @@ define i64 @ret2(i64 %a, i64 %b) { 388 ; CHECK: sllx %i0, 7, %i0 389 390 ; OPT-LABEL: shl_imm: 391-; OPT: jmp %o7+8 392+; OPT: retl 393 ; OPT: sllx %o0, 7, %o0 394 define i64 @shl_imm(i64 %a) { 395 %x = shl i64 %a, 7 396@@ -26,7 +26,7 @@ define i64 @shl_imm(i64 %a) { 397 ; CHECK: srax %i0, %i1, %i0 398 399 ; OPT-LABEL: sra_reg: 400-; OPT: jmp %o7+8 401+; OPT: retl 402 ; OPT: srax %o0, %o1, %o0 403 define i64 @sra_reg(i64 %a, i64 %b) { 404 %x = ashr i64 %a, %b 405@@ -42,7 +42,7 @@ define i64 @sra_reg(i64 %a, i64 %b) { 406 ; CHECK: or %g0, 0, %i0 407 408 ; OPT: ret_imm0 409-; OPT: jmp %o7+8 410+; OPT: retl 411 ; OPT: or %g0, 0, %o0 412 define i64 @ret_imm0() { 413 ret i64 0 414@@ -52,7 +52,7 @@ define i64 @ret_imm0() { 415 ; CHECK: or %g0, -4096, %i0 416 417 ; OPT: ret_simm13 418-; OPT: jmp %o7+8 419+; OPT: retl 420 ; OPT: or %g0, -4096, %o0 421 define i64 @ret_simm13() { 422 ret i64 -4096 423@@ -64,7 +64,7 @@ define i64 @ret_simm13() { 424 ; CHECK: restore 425 426 ; OPT: ret_sethi 427-; OPT: jmp %o7+8 428+; OPT: retl 429 ; OPT: sethi 4, %o0 430 define i64 @ret_sethi() { 431 ret i64 4096 432@@ -76,7 +76,7 @@ define i64 @ret_sethi() { 433 434 ; OPT: ret_sethi_or 435 ; OPT: sethi 4, [[R:%[go][0-7]]] 436-; OPT: jmp %o7+8 437+; OPT: retl 438 ; OPT: or [[R]], 1, %o0 439 440 define i64 @ret_sethi_or() { 441@@ -89,7 +89,7 @@ define i64 @ret_sethi_or() { 442 443 ; OPT: ret_nimm33 444 ; OPT: sethi 4, [[R:%[go][0-7]]] 445-; OPT: jmp %o7+8 446+; OPT: retl 447 ; OPT: xor [[R]], -4, %o0 448 449 define i64 @ret_nimm33() { 450Index: lib/Target/Sparc/SparcInstrAliases.td 451=================================================================== 452--- lib/Target/Sparc/SparcInstrAliases.td 453+++ lib/Target/Sparc/SparcInstrAliases.td 454@@ -128,3 +128,9 @@ def : InstAlias<"jmp $addr", (JMPLri G0, MEMri:$ad 455 // call addr -> jmpl addr, %o7 456 def : InstAlias<"call $addr", (JMPLrr O7, MEMrr:$addr)>; 457 def : InstAlias<"call $addr", (JMPLri O7, MEMri:$addr)>; 458+ 459+// retl -> RETL 8 460+def : InstAlias<"retl", (RETL 8)>; 461+ 462+// ret -> RET 8 463+def : InstAlias<"ret", (RET 8)>; 464