Pull in r198910 from upstream llvm trunk (by Venkatraman Govindaraju): [Sparc] Emit retl/ret instead of jmp instruction. It improves the readability of the assembly generated. Introduced here: http://svn.freebsd.org/changeset/base/262261 Index: test/CodeGen/SPARC/ctpop.ll =================================================================== --- test/CodeGen/SPARC/ctpop.ll +++ test/CodeGen/SPARC/ctpop.ll @@ -9,12 +9,12 @@ declare i32 @llvm.ctpop.i32(i32) ; V9-LABEL: test ; V9: srl %o0, 0, %o0 -; V9-NEXT: jmp %o7+8 +; V9-NEXT: retl ; V9-NEXT: popc %o0, %o0 ; SPARC64-LABEL: test ; SPARC64: srl %o0, 0, %o0 -; SPARC64: jmp %o7+8 +; SPARC64: retl ; SPARC64: popc %o0, %o0 define i32 @test(i32 %X) { Index: test/CodeGen/SPARC/2011-01-11-Call.ll =================================================================== --- test/CodeGen/SPARC/2011-01-11-Call.ll +++ test/CodeGen/SPARC/2011-01-11-Call.ll @@ -8,7 +8,7 @@ ; V8-NEXT: nop ; V8: call bar ; V8-NEXT: nop -; V8: jmp %i7+8 +; V8: ret ; V8-NEXT: restore ; V9-LABEL: test @@ -17,7 +17,7 @@ ; V9-NEXT: nop ; V9: call bar ; V9-NEXT: nop -; V9: jmp %i7+8 +; V9: ret ; V9-NEXT: restore define void @test() nounwind { @@ -36,7 +36,7 @@ declare void @bar(...) ; V8: save %sp ; V8: call foo ; V8-NEXT: nop -; V8: jmp %i7+8 +; V8: ret ; V8-NEXT: restore %g0, %o0, %o0 ; V9-LABEL: test_tail_call_with_return @@ -43,7 +43,7 @@ declare void @bar(...) ; V9: save %sp ; V9: call foo ; V9-NEXT: nop -; V9: jmp %i7+8 +; V9: ret ; V9-NEXT: restore %g0, %o0, %o0 define i32 @test_tail_call_with_return() nounwind { Index: test/CodeGen/SPARC/leafproc.ll =================================================================== --- test/CodeGen/SPARC/leafproc.ll +++ test/CodeGen/SPARC/leafproc.ll @@ -1,7 +1,7 @@ ; RUN: llc -march=sparc -disable-sparc-leaf-proc=0 < %s | FileCheck %s ; CHECK-LABEL: func_nobody: -; CHECK: jmp %o7+8 +; CHECK: retl ; CHECK-NEXT: nop define void @func_nobody() { entry: @@ -10,7 +10,7 @@ entry: ; CHECK-LABEL: return_int_const: -; CHECK: jmp %o7+8 +; CHECK: retl ; CHECK-NEXT: or %g0, 1729, %o0 define i32 @return_int_const() { entry: @@ -19,7 +19,7 @@ entry: ; CHECK-LABEL: return_double_const: ; CHECK: sethi -; CHECK: jmp %o7+8 +; CHECK: retl ; CHECK-NEXT: ldd {{.*}}, %f0 define double @return_double_const() { @@ -29,7 +29,7 @@ entry: ; CHECK-LABEL: leaf_proc_with_args: ; CHECK: add {{%o[0-1]}}, {{%o[0-1]}}, [[R:%[go][0-7]]] -; CHECK: jmp %o7+8 +; CHECK: retl ; CHECK-NEXT: add [[R]], %o2, %o0 define i32 @leaf_proc_with_args(i32 %a, i32 %b, i32 %c) { @@ -42,7 +42,7 @@ entry: ; CHECK-LABEL: leaf_proc_with_args_in_stack: ; CHECK-DAG: ld [%sp+92], {{%[go][0-7]}} ; CHECK-DAG: ld [%sp+96], {{%[go][0-7]}} -; CHECK: jmp %o7+8 +; CHECK: retl ; CHECK-NEXT: add {{.*}}, %o0 define i32 @leaf_proc_with_args_in_stack(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) { entry: @@ -63,7 +63,7 @@ entry: ; CHECK: or %g0, 2, [[R2:%[go][0-7]]] ; CHECK: st [[R2]], [%sp+100] ; CHECK: ld {{.+}}, %o0 -; CHECK: jmp %o7+8 +; CHECK: retl ; CHECK-NEXT: add %sp, 104, %sp define i32 @leaf_proc_with_local_array(i32 %a, i32 %b, i32 %c) { Index: test/CodeGen/SPARC/fp128.ll =================================================================== --- test/CodeGen/SPARC/fp128.ll +++ test/CodeGen/SPARC/fp128.ll @@ -45,7 +45,7 @@ entry: ; HARD: std %f{{.+}}, [%[[S1:.+]]] ; HARD-DAG: ldd [%[[S0]]], %f{{.+}} ; HARD-DAG: ldd [%[[S1]]], %f{{.+}} -; HARD: jmp +; HARD: jmp %o7+12 ; SOFT-LABEL: f128_spill ; SOFT: std %f{{.+}}, [%[[S0:.+]]] @@ -52,7 +52,7 @@ entry: ; SOFT: std %f{{.+}}, [%[[S1:.+]]] ; SOFT-DAG: ldd [%[[S0]]], %f{{.+}} ; SOFT-DAG: ldd [%[[S1]]], %f{{.+}} -; SOFT: jmp +; SOFT: jmp %o7+12 define void @f128_spill(fp128* noalias sret %scalar.result, fp128* byval %a) { entry: @@ -132,13 +132,13 @@ entry: ; HARD: ldub ; HARD: faddq ; HARD: stb -; HARD: jmp +; HARD: ret ; SOFT-LABEL: fp128_unaligned ; SOFT: ldub ; SOFT: call _Q_add ; SOFT: stb -; SOFT: jmp +; SOFT: ret define void @fp128_unaligned(fp128* %a, fp128* %b, fp128* %c) { entry: Index: test/CodeGen/SPARC/2011-01-11-FrameAddr.ll =================================================================== --- test/CodeGen/SPARC/2011-01-11-FrameAddr.ll +++ test/CodeGen/SPARC/2011-01-11-FrameAddr.ll @@ -9,18 +9,18 @@ define i8* @frameaddr() nounwind readnone { entry: ;V8-LABEL: frameaddr: ;V8: save %sp, -96, %sp -;V8: jmp %i7+8 +;V8: ret ;V8: restore %g0, %fp, %o0 ;V9-LABEL: frameaddr: ;V9: save %sp, -96, %sp -;V9: jmp %i7+8 +;V9: ret ;V9: restore %g0, %fp, %o0 ;SPARC64-LABEL: frameaddr ;SPARC64: save %sp, -128, %sp ;SPARC64: add %fp, 2047, %i0 -;SPARC64: jmp %i7+8 +;SPARC64: ret ;SPARC64: restore %g0, %g0, %g0 %0 = tail call i8* @llvm.frameaddress(i32 0) Index: test/CodeGen/SPARC/constpool.ll =================================================================== --- test/CodeGen/SPARC/constpool.ll +++ test/CodeGen/SPARC/constpool.ll @@ -12,7 +12,7 @@ entry: ; abs32: floatCP ; abs32: sethi %hi(.LCPI0_0), %[[R:[gilo][0-7]]] -; abs32: jmp %o7+8 +; abs32: retl ; abs32: ld [%[[R]]+%lo(.LCPI0_0)], %f @@ -20,7 +20,7 @@ entry: ; abs44: sethi %h44(.LCPI0_0), %[[R1:[gilo][0-7]]] ; abs44: add %[[R1]], %m44(.LCPI0_0), %[[R2:[gilo][0-7]]] ; abs44: sllx %[[R2]], 12, %[[R3:[gilo][0-7]]] -; abs44: jmp %o7+8 +; abs44: retl ; abs44: ld [%[[R3]]+%l44(.LCPI0_0)], %f1 @@ -30,7 +30,7 @@ entry: ; abs64: sethi %hh(.LCPI0_0), %[[R3:[gilo][0-7]]] ; abs64: add %[[R3]], %hm(.LCPI0_0), %[[R4:[gilo][0-7]]] ; abs64: sllx %[[R4]], 32, %[[R5:[gilo][0-7]]] -; abs64: jmp %o7+8 +; abs64: retl ; abs64: ld [%[[R5]]+%[[R2]]], %f1 @@ -40,7 +40,7 @@ entry: ; v8pic32: add %[[R1]], %lo(.LCPI0_0), %[[Goffs:[gilo][0-7]]] ; v8pic32: ld [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]] ; v8pic32: ld [%[[Gaddr]]], %f0 -; v8pic32: jmp %i7+8 +; v8pic32: ret ; v8pic32: restore @@ -51,7 +51,7 @@ entry: ; v9pic32: add %[[R1]], %lo(.LCPI0_0), %[[Goffs:[gilo][0-7]]] ; v9pic32: ldx [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]] ; v9pic32: ld [%[[Gaddr]]], %f1 -; v9pic32: jmp %i7+8 +; v9pic32: ret ; v9pic32: restore Index: test/CodeGen/SPARC/globals.ll =================================================================== --- test/CodeGen/SPARC/globals.ll +++ test/CodeGen/SPARC/globals.ll @@ -14,7 +14,7 @@ define zeroext i8 @loadG() { ; abs32: loadG ; abs32: sethi %hi(G), %[[R:[gilo][0-7]]] -; abs32: jmp %o7+8 +; abs32: retl ; abs32: ldub [%[[R]]+%lo(G)], %o0 @@ -22,7 +22,7 @@ define zeroext i8 @loadG() { ; abs44: sethi %h44(G), %[[R1:[gilo][0-7]]] ; abs44: add %[[R1]], %m44(G), %[[R2:[gilo][0-7]]] ; abs44: sllx %[[R2]], 12, %[[R3:[gilo][0-7]]] -; abs44: jmp %o7+8 +; abs44: retl ; abs44: ldub [%[[R3]]+%l44(G)], %o0 @@ -32,7 +32,7 @@ define zeroext i8 @loadG() { ; abs64: sethi %hh(G), %[[R3:[gilo][0-7]]] ; abs64: add %[[R3]], %hm(G), %[[R4:[gilo][0-7]]] ; abs64: sllx %[[R4]], 32, %[[R5:[gilo][0-7]]] -; abs64: jmp %o7+8 +; abs64: retl ; abs64: ldub [%[[R5]]+%[[R2]]], %o0 @@ -42,7 +42,7 @@ define zeroext i8 @loadG() { ; v8pic32: add %[[R1]], %lo(G), %[[Goffs:[gilo][0-7]]] ; v8pic32: ld [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]] ; v8pic32: ldub [%[[Gaddr]]], %i0 -; v8pic32: jmp %i7+8 +; v8pic32: ret ; v8pic32: restore @@ -52,6 +52,6 @@ define zeroext i8 @loadG() { ; v9pic32: add %[[R1]], %lo(G), %[[Goffs:[gilo][0-7]]] ; v9pic32: ldx [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]] ; v9pic32: ldub [%[[Gaddr]]], %i0 -; v9pic32: jmp %i7+8 +; v9pic32: ret ; v9pic32: restore Index: test/CodeGen/SPARC/rem.ll =================================================================== --- test/CodeGen/SPARC/rem.ll +++ test/CodeGen/SPARC/rem.ll @@ -3,7 +3,7 @@ ; CHECK-LABEL: test1: ; CHECK: sdivx %o0, %o1, %o2 ; CHECK-NEXT: mulx %o2, %o1, %o1 -; CHECK-NEXT: jmp %o7+8 +; CHECK-NEXT: retl ; CHECK-NEXT: sub %o0, %o1, %o0 define i64 @test1(i64 %X, i64 %Y) { @@ -14,7 +14,7 @@ define i64 @test1(i64 %X, i64 %Y) { ; CHECK-LABEL: test2: ; CHECK: udivx %o0, %o1, %o2 ; CHECK-NEXT: mulx %o2, %o1, %o1 -; CHECK-NEXT: jmp %o7+8 +; CHECK-NEXT: retl ; CHECK-NEXT: sub %o0, %o1, %o0 define i64 @test2(i64 %X, i64 %Y) { Index: test/CodeGen/SPARC/2011-01-19-DelaySlot.ll =================================================================== --- test/CodeGen/SPARC/2011-01-19-DelaySlot.ll +++ test/CodeGen/SPARC/2011-01-19-DelaySlot.ll @@ -7,7 +7,7 @@ entry: ; CHECK: test ; CHECK: call bar ; CHECK-NOT: nop -; CHECK: jmp +; CHECK: ret ; CHECK-NEXT: restore %0 = tail call i32 @bar(i32 %a) nounwind ret i32 %0 @@ -18,7 +18,7 @@ entry: ; CHECK: test_jmpl ; CHECK: call ; CHECK-NOT: nop -; CHECK: jmp +; CHECK: ret ; CHECK-NEXT: restore %0 = tail call i32 %f(i32 %a, i32 %b) nounwind ret i32 %0 @@ -47,7 +47,7 @@ bb: bb5: ; preds = %bb, %entry %a_addr.1.lcssa = phi i32 [ %a, %entry ], [ %a_addr.0, %bb ] -;CHECK: jmp +;CHECK: retl ;CHECK-NOT: restore ret i32 %a_addr.1.lcssa } @@ -110,7 +110,7 @@ declare i32 @func(i32*) define i32 @restore_add(i32 %a, i32 %b) { entry: ;CHECK-LABEL: restore_add: -;CHECK: jmp %i7+8 +;CHECK: ret ;CHECK: restore %o0, %i1, %o0 %0 = tail call i32 @bar(i32 %a) nounwind %1 = add nsw i32 %0, %b @@ -120,7 +120,7 @@ entry: define i32 @restore_add_imm(i32 %a) { entry: ;CHECK-LABEL: restore_add_imm: -;CHECK: jmp %i7+8 +;CHECK: ret ;CHECK: restore %o0, 20, %o0 %0 = tail call i32 @bar(i32 %a) nounwind %1 = add nsw i32 %0, 20 @@ -130,7 +130,7 @@ entry: define i32 @restore_or(i32 %a) { entry: ;CHECK-LABEL: restore_or: -;CHECK: jmp %i7+8 +;CHECK: ret ;CHECK: restore %g0, %o0, %o0 %0 = tail call i32 @bar(i32 %a) nounwind ret i32 %0 @@ -140,7 +140,7 @@ define i32 @restore_or_imm(i32 %a) { entry: ;CHECK-LABEL: restore_or_imm: ;CHECK: or %o0, 20, %i0 -;CHECK: jmp %i7+8 +;CHECK: ret ;CHECK: restore %g0, %g0, %g0 %0 = tail call i32 @bar(i32 %a) nounwind %1 = or i32 %0, 20 Index: test/CodeGen/SPARC/64bit.ll =================================================================== --- test/CodeGen/SPARC/64bit.ll +++ test/CodeGen/SPARC/64bit.ll @@ -5,7 +5,7 @@ ; CHECK: or %g0, %i1, %i0 ; OPT-LABEL: ret2: -; OPT: jmp %o7+8 +; OPT: retl ; OPT: or %g0, %o1, %o0 define i64 @ret2(i64 %a, i64 %b) { ret i64 %b @@ -15,7 +15,7 @@ define i64 @ret2(i64 %a, i64 %b) { ; CHECK: sllx %i0, 7, %i0 ; OPT-LABEL: shl_imm: -; OPT: jmp %o7+8 +; OPT: retl ; OPT: sllx %o0, 7, %o0 define i64 @shl_imm(i64 %a) { %x = shl i64 %a, 7 @@ -26,7 +26,7 @@ define i64 @shl_imm(i64 %a) { ; CHECK: srax %i0, %i1, %i0 ; OPT-LABEL: sra_reg: -; OPT: jmp %o7+8 +; OPT: retl ; OPT: srax %o0, %o1, %o0 define i64 @sra_reg(i64 %a, i64 %b) { %x = ashr i64 %a, %b @@ -42,7 +42,7 @@ define i64 @sra_reg(i64 %a, i64 %b) { ; CHECK: or %g0, 0, %i0 ; OPT: ret_imm0 -; OPT: jmp %o7+8 +; OPT: retl ; OPT: or %g0, 0, %o0 define i64 @ret_imm0() { ret i64 0 @@ -52,7 +52,7 @@ define i64 @ret_imm0() { ; CHECK: or %g0, -4096, %i0 ; OPT: ret_simm13 -; OPT: jmp %o7+8 +; OPT: retl ; OPT: or %g0, -4096, %o0 define i64 @ret_simm13() { ret i64 -4096 @@ -64,7 +64,7 @@ define i64 @ret_simm13() { ; CHECK: restore ; OPT: ret_sethi -; OPT: jmp %o7+8 +; OPT: retl ; OPT: sethi 4, %o0 define i64 @ret_sethi() { ret i64 4096 @@ -76,7 +76,7 @@ define i64 @ret_sethi() { ; OPT: ret_sethi_or ; OPT: sethi 4, [[R:%[go][0-7]]] -; OPT: jmp %o7+8 +; OPT: retl ; OPT: or [[R]], 1, %o0 define i64 @ret_sethi_or() { @@ -89,7 +89,7 @@ define i64 @ret_sethi_or() { ; OPT: ret_nimm33 ; OPT: sethi 4, [[R:%[go][0-7]]] -; OPT: jmp %o7+8 +; OPT: retl ; OPT: xor [[R]], -4, %o0 define i64 @ret_nimm33() { Index: lib/Target/Sparc/SparcInstrAliases.td =================================================================== --- lib/Target/Sparc/SparcInstrAliases.td +++ lib/Target/Sparc/SparcInstrAliases.td @@ -128,3 +128,9 @@ def : InstAlias<"jmp $addr", (JMPLri G0, MEMri:$ad // call addr -> jmpl addr, %o7 def : InstAlias<"call $addr", (JMPLrr O7, MEMrr:$addr)>; def : InstAlias<"call $addr", (JMPLri O7, MEMri:$addr)>; + +// retl -> RETL 8 +def : InstAlias<"retl", (RETL 8)>; + +// ret -> RET 8 +def : InstAlias<"ret", (RET 8)>;