llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-loongarch Author: wanglei (wangleiat) <details> <summary>Changes</summary> Micro-architecture unconditionally treats a "jr $ra" as "return from subroutine", hence doing "jr $ra" would interfere with both subroutine return prediction and the more general indirect branch prediction. GCC thread: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110136 --- Full diff: https://github.com/llvm/llvm-project/pull/115424.diff 3 Files Affected: - (modified) llvm/lib/Target/LoongArch/LoongArchInstrInfo.td (+4-4) - (modified) llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td (+6) - (modified) llvm/test/CodeGen/LoongArch/jr-without-ra.ll (+5-5) ``````````diff diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td index ccdd5165728231..3de20d6e599dbf 100644 --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -1469,12 +1469,12 @@ def PseudoBR : Pseudo<(outs), (ins simm26_b:$imm26), [(br bb:$imm26)]>, PseudoInstExpansion<(B simm26_b:$imm26)>; let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in -def PseudoBRIND : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>, +def PseudoBRIND : Pseudo<(outs), (ins GPRJR:$rj, simm16_lsl2:$imm16)>, PseudoInstExpansion<(JIRL R0, GPR:$rj, simm16_lsl2:$imm16)>; -def : Pat<(brind GPR:$rj), (PseudoBRIND GPR:$rj, 0)>; -def : Pat<(brind (add GPR:$rj, simm16_lsl2:$imm16)), - (PseudoBRIND GPR:$rj, simm16_lsl2:$imm16)>; +def : Pat<(brind GPRJR:$rj), (PseudoBRIND GPRJR:$rj, 0)>; +def : Pat<(brind (add GPRJR:$rj, simm16_lsl2:$imm16)), + (PseudoBRIND GPRJR:$rj, simm16_lsl2:$imm16)>; // Function call with 'Small' code model. let isCall = 1, Defs = [R1] in diff --git a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td index 2d3a7c364f0bf4..a8419980868ee1 100644 --- a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td @@ -121,6 +121,12 @@ def GPR : GPRRegisterClass<(add // Argument registers (a0...a7) def GPRT : GPRRegisterClass<(add // a0...a7, t0...t8 (sequence "R%u", 4, 20))>; +// Don't use R1 for JR since that micro-architecture unconditionally treats a +// "jr $ra" as "return from subroutine", hence doing "jr $ra" would interfere +// with both subroutine return prediction and the more general indirect branch +// prediction. +def GPRJR : GPRRegisterClass<(sub GPR, R1)>; + // Floating point registers let RegAltNameIndices = [RegAliasName] in { diff --git a/llvm/test/CodeGen/LoongArch/jr-without-ra.ll b/llvm/test/CodeGen/LoongArch/jr-without-ra.ll index f32513deee82bd..d1c4459aaa6ee0 100644 --- a/llvm/test/CodeGen/LoongArch/jr-without-ra.ll +++ b/llvm/test/CodeGen/LoongArch/jr-without-ra.ll @@ -44,7 +44,6 @@ define void @jr_without_ra(ptr %rtwdev, ptr %chan, ptr %h2c, i8 %.pre, i1 %cmp.i ; CHECK-NEXT: addi.w $s4, $zero, -41 ; CHECK-NEXT: ori $s3, $zero, 1 ; CHECK-NEXT: slli.d $s4, $s4, 3 -; CHECK-NEXT: ori $s5, $zero, 50 ; CHECK-NEXT: ori $s6, $zero, 3 ; CHECK-NEXT: lu32i.d $s6, 262144 ; CHECK-NEXT: b .LBB0_4 @@ -54,8 +53,8 @@ define void @jr_without_ra(ptr %rtwdev, ptr %chan, ptr %h2c, i8 %.pre, i1 %cmp.i ; CHECK-NEXT: ori $s8, $zero, 1 ; CHECK-NEXT: .LBB0_2: # %if.else.i106 ; CHECK-NEXT: # in Loop: Header=BB0_4 Depth=1 -; CHECK-NEXT: alsl.d $ra, $s0, $s0, 3 -; CHECK-NEXT: alsl.d $s0, $ra, $s0, 1 +; CHECK-NEXT: alsl.d $s5, $s0, $s0, 3 +; CHECK-NEXT: alsl.d $s0, $s5, $s0, 1 ; CHECK-NEXT: add.d $s0, $t0, $s0 ; CHECK-NEXT: ldx.bu $s8, $s0, $s8 ; CHECK-NEXT: .LBB0_3: # %phy_tssi_get_ofdm_de.exit @@ -92,6 +91,7 @@ define void @jr_without_ra(ptr %rtwdev, ptr %chan, ptr %h2c, i8 %.pre, i1 %cmp.i ; CHECK-NEXT: .LBB0_9: # %if.end.i ; CHECK-NEXT: # in Loop: Header=BB0_4 Depth=1 ; CHECK-NEXT: andi $s7, $s7, 255 +; CHECK-NEXT: ori $s5, $zero, 50 ; CHECK-NEXT: bltu $s5, $s7, .LBB0_15 ; CHECK-NEXT: # %bb.10: # %if.end.i ; CHECK-NEXT: # in Loop: Header=BB0_4 Depth=1 @@ -113,8 +113,8 @@ define void @jr_without_ra(ptr %rtwdev, ptr %chan, ptr %h2c, i8 %.pre, i1 %cmp.i ; CHECK-NEXT: # in Loop: Header=BB0_4 Depth=1 ; CHECK-NEXT: pcalau12i $ra, %pc_hi20(.LJTI0_1) ; CHECK-NEXT: addi.d $ra, $ra, %pc_lo12(.LJTI0_1) -; CHECK-NEXT: ldx.d $ra, $s4, $ra -; CHECK-NEXT: ret +; CHECK-NEXT: ldx.d $s5, $s4, $ra +; CHECK-NEXT: jr $s5 ; CHECK-NEXT: .LBB0_13: # %phy_tssi_get_ofdm_trim_de.exit ; CHECK-NEXT: # in Loop: Header=BB0_4 Depth=1 ; CHECK-NEXT: bnez $s3, .LBB0_1 `````````` </details> https://github.com/llvm/llvm-project/pull/115424 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits