[llvm-branch-commits] [llvm] release/19.x: [RISCV] Fix InsnCI register type (#100113) (PR #100306)
https://github.com/lenary approved this pull request. https://github.com/llvm/llvm-project/pull/100306 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/19.x: [RISCV] Fix InsnCI register type (#100113) (PR #100306)
lenary wrote: The build failures aren't related. I'm going to hit the rebase button in the hope that fixes the build issue. https://github.com/llvm/llvm-project/pull/100306 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/19.x: [RISCV] Fix InsnCI register type (#100113) (PR #100306)
https://github.com/lenary updated https://github.com/llvm/llvm-project/pull/100306 >From f9d32a6882749e761e971f9237dde813ddbba2d7 Mon Sep 17 00:00:00 2001 From: Sudharsan Veeravalli Date: Tue, 23 Jul 2024 18:49:57 +0530 Subject: [PATCH] [RISCV] Fix InsnCI register type (#100113) According to the spec the CI type instructions can take any of the 32 RVI registers. Fixes #100112 (cherry picked from commit 1ebfc81a91194c000ac70b4ea53891cc956aa6eb) --- llvm/lib/Target/RISCV/RISCVInstrInfoC.td | 8 llvm/test/MC/RISCV/insn_c.s | 10 ++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td index 9257ee5a09a8e..3f279b7a58ca6 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -764,9 +764,9 @@ def InsnCR : DirectiveInsnCR<(outs AnyReg:$rd), (ins uimm2_opcode:$opcode, uimm4:$funct4, AnyReg:$rs2), "$opcode, $funct4, $rd, $rs2">; -def InsnCI : DirectiveInsnCI<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode, - uimm3:$funct3, - simm6:$imm6), +def InsnCI : DirectiveInsnCI<(outs AnyReg:$rd), (ins uimm2_opcode:$opcode, + uimm3:$funct3, + simm6:$imm6), "$opcode, $funct3, $rd, $imm6">; def InsnCIW : DirectiveInsnCIW<(outs AnyRegC:$rd), (ins uimm2_opcode:$opcode, uimm3:$funct3, @@ -818,7 +818,7 @@ def : InstAlias<".insn_cr $opcode, $funct4, $rd, $rs2", (InsnCR AnyReg:$rd, uimm2_opcode:$opcode, uimm4:$funct4, AnyReg:$rs2)>; def : InstAlias<".insn_ci $opcode, $funct3, $rd, $imm6", -(InsnCI AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3, +(InsnCI AnyReg:$rd, uimm2_opcode:$opcode, uimm3:$funct3, simm6:$imm6)>; def : InstAlias<".insn_ciw $opcode, $funct3, $rd, $imm8", (InsnCIW AnyRegC:$rd, uimm2_opcode:$opcode, uimm3:$funct3, diff --git a/llvm/test/MC/RISCV/insn_c.s b/llvm/test/MC/RISCV/insn_c.s index 19169e8b08c94..c63e8ab33aef9 100644 --- a/llvm/test/MC/RISCV/insn_c.s +++ b/llvm/test/MC/RISCV/insn_c.s @@ -31,6 +31,16 @@ target: # CHECK-OBJ: c.addi a0, 0xd .insn ci C1, 0, a0, 13 +# CHECK-ASM: .insn ci 1, 0, a6, 13 +# CHECK-ASM: encoding: [0x35,0x08] +# CHECK-OBJ: c.addi a6, 0xd +.insn ci 1, 0, a6, 13 + +# CHECK-ASM: .insn ci 1, 0, a6, 13 +# CHECK-ASM: encoding: [0x35,0x08] +# CHECK-OBJ: c.addi a6, 0xd +.insn ci C1, 0, a6, 13 + # CHECK-ASM: .insn ciw 0, 0, a0, 13 # CHECK-ASM: encoding: [0xa8,0x01] # CHECK-OBJ: c.addi4spn a0, sp, 0xc8 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/19.x: [RISCV] Don't outline pcrel_lo when the function has a section prefix (#107943) (PR #108288)
lenary wrote: I believe the risk of bringing this in to be fairly small (we did the smallest fix possible to make it more amenable to back-porting), but I also knew this was fairly close to the 19.1.0 release date. If you think there will be a 19.1.1, then it can probably wait for that. https://github.com/llvm/llvm-project/pull/108288 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 71ed4b6 - [RISCV] Legalize select when Zbt extension available
Author: Michael Munday Date: 2021-01-12T21:24:38Z New Revision: 71ed4b6ce57d8843ef705af8f98305976a8f107a URL: https://github.com/llvm/llvm-project/commit/71ed4b6ce57d8843ef705af8f98305976a8f107a DIFF: https://github.com/llvm/llvm-project/commit/71ed4b6ce57d8843ef705af8f98305976a8f107a.diff LOG: [RISCV] Legalize select when Zbt extension available The custom expansion of select operations in the RISC-V backend interferes with the matching of cmov instructions. Legalizing select when the Zbt extension is available solves that problem. Reviewed By: lenary, craig.topper Differential Revision: https://reviews.llvm.org/D93767 Added: Modified: llvm/lib/Target/RISCV/RISCVISelLowering.cpp llvm/lib/Target/RISCV/RISCVInstrInfoB.td llvm/test/CodeGen/RISCV/rv32Zbb.ll llvm/test/CodeGen/RISCV/rv32Zbbp.ll llvm/test/CodeGen/RISCV/rv32Zbs.ll llvm/test/CodeGen/RISCV/rv32Zbt.ll llvm/test/CodeGen/RISCV/rv64Zbt.ll Removed: diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 03db9911c867..73bc83b558ad 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -162,7 +162,6 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, setOperationAction(ISD::BR_JT, MVT::Other, Expand); setOperationAction(ISD::BR_CC, XLenVT, Expand); - setOperationAction(ISD::SELECT, XLenVT, Custom); setOperationAction(ISD::SELECT_CC, XLenVT, Expand); setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); @@ -249,11 +248,14 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, if (Subtarget.hasStdExtZbt()) { setOperationAction(ISD::FSHL, XLenVT, Legal); setOperationAction(ISD::FSHR, XLenVT, Legal); +setOperationAction(ISD::SELECT, XLenVT, Legal); if (Subtarget.is64Bit()) { setOperationAction(ISD::FSHL, MVT::i32, Custom); setOperationAction(ISD::FSHR, MVT::i32, Custom); } + } else { +setOperationAction(ISD::SELECT, XLenVT, Custom); } ISD::CondCode FPCCToExpand[] = { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td index ce6cb6ba82ce..47740308518f 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td @@ -797,7 +797,23 @@ def : Pat<(rotl (riscv_grevi GPR:$rs1, (i32 24)), (i32 16)), (GREVI GPR:$rs1, 8) let Predicates = [HasStdExtZbt] in { def : Pat<(or (and (not GPR:$rs2), GPR:$rs3), (and GPR:$rs2, GPR:$rs1)), (CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>; -def : Pat<(riscv_selectcc GPR:$rs2, (XLenVT 0), (XLenVT 17), GPR:$rs3, GPR:$rs1), +def : Pat<(select (XLenVT (setne GPR:$rs2, 0)), GPR:$rs1, GPR:$rs3), + (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>; +def : Pat<(select (XLenVT (seteq GPR:$rs2, 0)), GPR:$rs3, GPR:$rs1), + (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>; +def : Pat<(select (XLenVT (seteq GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs3), + (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>; +def : Pat<(select (XLenVT (setne GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1), + (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>; +def : Pat<(select (XLenVT (setuge GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs3), + (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>; +def : Pat<(select (XLenVT (setule GPR:$y, GPR:$x)), GPR:$rs1, GPR:$rs3), + (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>; +def : Pat<(select (XLenVT (setge GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs3), + (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>; +def : Pat<(select (XLenVT (setle GPR:$y, GPR:$x)), GPR:$rs1, GPR:$rs3), + (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>; +def : Pat<(select GPR:$rs2, GPR:$rs3, GPR:$rs1), (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>; } // Predicates = [HasStdExtZbt] diff --git a/llvm/test/CodeGen/RISCV/rv32Zbb.ll b/llvm/test/CodeGen/RISCV/rv32Zbb.ll index b95fcd5f5232..90ea5629aae6 100644 --- a/llvm/test/CodeGen/RISCV/rv32Zbb.ll +++ b/llvm/test/CodeGen/RISCV/rv32Zbb.ll @@ -60,14 +60,7 @@ define i64 @slo_i64(i64 %a, i64 %b) nounwind { ; ; RV32IB-LABEL: slo_i64: ; RV32IB: # %bb.0: -; RV32IB-NEXT:addi a3, a2, -32 ; RV32IB-NEXT:not a0, a0 -; RV32IB-NEXT:bltz a3, .LBB1_2 -; RV32IB-NEXT: # %bb.1: -; RV32IB-NEXT:mv a2, zero -; RV32IB-NEXT:sll a1, a0, a3 -; RV32IB-NEXT:j .LBB1_3 -; RV32IB-NEXT: .LBB1_2: ; RV32IB-NEXT:not a1, a1 ; RV32IB-NEXT:sll a1, a1, a2 ; RV32IB-NEXT:addi a3, zero, 31 @@ -75,10 +68,15 @@ define i64 @slo_i64(i64 %a, i64 %b) nounwind { ; RV32IB-NEXT:srli a4, a0, 1 ; RV32IB-NEXT:srl a3, a4, a3 ; RV32IB-NEXT:or a1, a1, a3 -; RV32IB-NEXT:sll a2, a0, a2 -; RV32IB-NEXT: .LBB1_3: +; RV32IB-NEXT:addi a3, a2, -32 +; RV32IB-NEXT:sll a4, a0, a3 +; RV32IB-NEXT:slti a5, a3, 0 +; RV32IB-NEXT:cmov a
[llvm-branch-commits] [llvm] 7c9c2a2 - Revert "[RISCV] Legalize select when Zbt extension available"
Author: Sam Elliott Date: 2021-01-14T16:44:34Z New Revision: 7c9c2a2ea5e3760d7310309c96c9a4ce41fa4d9b URL: https://github.com/llvm/llvm-project/commit/7c9c2a2ea5e3760d7310309c96c9a4ce41fa4d9b DIFF: https://github.com/llvm/llvm-project/commit/7c9c2a2ea5e3760d7310309c96c9a4ce41fa4d9b.diff LOG: Revert "[RISCV] Legalize select when Zbt extension available" We found issues with this patch in additional testing. Backing out while we work on a fix. This reverts commit 71ed4b6ce57d8843ef705af8f98305976a8f107a. Added: Modified: llvm/lib/Target/RISCV/RISCVISelLowering.cpp llvm/lib/Target/RISCV/RISCVInstrInfoB.td llvm/test/CodeGen/RISCV/rv32Zbb.ll llvm/test/CodeGen/RISCV/rv32Zbbp.ll llvm/test/CodeGen/RISCV/rv32Zbs.ll llvm/test/CodeGen/RISCV/rv32Zbt.ll llvm/test/CodeGen/RISCV/rv64Zbt.ll Removed: diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index e84c2e9e368e..6055dd826e0d 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -163,6 +163,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, setOperationAction(ISD::BR_JT, MVT::Other, Expand); setOperationAction(ISD::BR_CC, XLenVT, Expand); + setOperationAction(ISD::SELECT, XLenVT, Custom); setOperationAction(ISD::SELECT_CC, XLenVT, Expand); setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); @@ -249,14 +250,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, if (Subtarget.hasStdExtZbt()) { setOperationAction(ISD::FSHL, XLenVT, Legal); setOperationAction(ISD::FSHR, XLenVT, Legal); -setOperationAction(ISD::SELECT, XLenVT, Legal); if (Subtarget.is64Bit()) { setOperationAction(ISD::FSHL, MVT::i32, Custom); setOperationAction(ISD::FSHR, MVT::i32, Custom); } - } else { -setOperationAction(ISD::SELECT, XLenVT, Custom); } ISD::CondCode FPCCToExpand[] = { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td index 47740308518f..ce6cb6ba82ce 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td @@ -797,23 +797,7 @@ def : Pat<(rotl (riscv_grevi GPR:$rs1, (i32 24)), (i32 16)), (GREVI GPR:$rs1, 8) let Predicates = [HasStdExtZbt] in { def : Pat<(or (and (not GPR:$rs2), GPR:$rs3), (and GPR:$rs2, GPR:$rs1)), (CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>; -def : Pat<(select (XLenVT (setne GPR:$rs2, 0)), GPR:$rs1, GPR:$rs3), - (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>; -def : Pat<(select (XLenVT (seteq GPR:$rs2, 0)), GPR:$rs3, GPR:$rs1), - (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>; -def : Pat<(select (XLenVT (seteq GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs3), - (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>; -def : Pat<(select (XLenVT (setne GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1), - (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>; -def : Pat<(select (XLenVT (setuge GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs3), - (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>; -def : Pat<(select (XLenVT (setule GPR:$y, GPR:$x)), GPR:$rs1, GPR:$rs3), - (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>; -def : Pat<(select (XLenVT (setge GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs3), - (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>; -def : Pat<(select (XLenVT (setle GPR:$y, GPR:$x)), GPR:$rs1, GPR:$rs3), - (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>; -def : Pat<(select GPR:$rs2, GPR:$rs3, GPR:$rs1), +def : Pat<(riscv_selectcc GPR:$rs2, (XLenVT 0), (XLenVT 17), GPR:$rs3, GPR:$rs1), (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>; } // Predicates = [HasStdExtZbt] diff --git a/llvm/test/CodeGen/RISCV/rv32Zbb.ll b/llvm/test/CodeGen/RISCV/rv32Zbb.ll index 90ea5629aae6..b95fcd5f5232 100644 --- a/llvm/test/CodeGen/RISCV/rv32Zbb.ll +++ b/llvm/test/CodeGen/RISCV/rv32Zbb.ll @@ -60,7 +60,14 @@ define i64 @slo_i64(i64 %a, i64 %b) nounwind { ; ; RV32IB-LABEL: slo_i64: ; RV32IB: # %bb.0: +; RV32IB-NEXT:addi a3, a2, -32 ; RV32IB-NEXT:not a0, a0 +; RV32IB-NEXT:bltz a3, .LBB1_2 +; RV32IB-NEXT: # %bb.1: +; RV32IB-NEXT:mv a2, zero +; RV32IB-NEXT:sll a1, a0, a3 +; RV32IB-NEXT:j .LBB1_3 +; RV32IB-NEXT: .LBB1_2: ; RV32IB-NEXT:not a1, a1 ; RV32IB-NEXT:sll a1, a1, a2 ; RV32IB-NEXT:addi a3, zero, 31 @@ -68,15 +75,10 @@ define i64 @slo_i64(i64 %a, i64 %b) nounwind { ; RV32IB-NEXT:srli a4, a0, 1 ; RV32IB-NEXT:srl a3, a4, a3 ; RV32IB-NEXT:or a1, a1, a3 -; RV32IB-NEXT:addi a3, a2, -32 -; RV32IB-NEXT:sll a4, a0, a3 -; RV32IB-NEXT:slti a5, a3, 0 -; RV32IB-NEXT:cmov a1, a5, a4, a1 -; RV32IB-NEXT:sll a0, a0, a2 -; RV32IB-NEXT:srai a2, a3, 31 -; RV32IB-NEXT:and a0, a2, a0 +; RV32IB-NEXT:sll a2, a0, a2 +; RV32IB-NEXT: .LBB1_3: ; R
[llvm-branch-commits] [llvm] 8a53a73 - [RISCV][NFC] Regenerate Calling Convention Tests
Author: Sam Elliott Date: 2021-01-14T22:35:17Z New Revision: 8a53a7375a86a5a89ba124de9e17aa5701544104 URL: https://github.com/llvm/llvm-project/commit/8a53a7375a86a5a89ba124de9e17aa5701544104 DIFF: https://github.com/llvm/llvm-project/commit/8a53a7375a86a5a89ba124de9e17aa5701544104.diff LOG: [RISCV][NFC] Regenerate Calling Convention Tests This regenerates these tests using utils/update_llc_test_checks.py so that future changes in this area don't have the noise of lots of `@plt` lines being added. I also removed the `nounwind`s from the stack-realignment.ll test to increase coverage on the generated call frame information. Added: Modified: llvm/test/CodeGen/RISCV/callee-saved-fpr32s.ll llvm/test/CodeGen/RISCV/callee-saved-fpr64s.ll llvm/test/CodeGen/RISCV/callee-saved-gprs.ll llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-common.ll llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll llvm/test/CodeGen/RISCV/calling-conv-ilp32.ll llvm/test/CodeGen/RISCV/calling-conv-ilp32d.ll llvm/test/CodeGen/RISCV/calling-conv-ilp32f-ilp32d-common.ll llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-common.ll llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll llvm/test/CodeGen/RISCV/calling-conv-lp64.ll llvm/test/CodeGen/RISCV/calling-conv-rv32f-ilp32.ll llvm/test/CodeGen/RISCV/stack-realignment.ll llvm/test/CodeGen/RISCV/vararg.ll Removed: diff --git a/llvm/test/CodeGen/RISCV/callee-saved-fpr32s.ll b/llvm/test/CodeGen/RISCV/callee-saved-fpr32s.ll index e213d1f3b594..d8d904ac85c6 100644 --- a/llvm/test/CodeGen/RISCV/callee-saved-fpr32s.ll +++ b/llvm/test/CodeGen/RISCV/callee-saved-fpr32s.ll @@ -629,7 +629,7 @@ define void @caller() nounwind { ; ILP32-NEXT:fsw ft0, 8(sp) # 4-byte Folded Spill ; ILP32-NEXT:flw ft0, 124(s1) ; ILP32-NEXT:fsw ft0, 4(sp) # 4-byte Folded Spill -; ILP32-NEXT:call callee +; ILP32-NEXT:call callee@plt ; ILP32-NEXT:flw ft0, 4(sp) # 4-byte Folded Reload ; ILP32-NEXT:fsw ft0, 124(s1) ; ILP32-NEXT:flw ft0, 8(sp) # 4-byte Folded Reload @@ -772,7 +772,7 @@ define void @caller() nounwind { ; LP64-NEXT:fsw ft0, 12(sp) # 4-byte Folded Spill ; LP64-NEXT:flw ft0, 124(s1) ; LP64-NEXT:fsw ft0, 8(sp) # 4-byte Folded Spill -; LP64-NEXT:call callee +; LP64-NEXT:call callee@plt ; LP64-NEXT:flw ft0, 8(sp) # 4-byte Folded Reload ; LP64-NEXT:fsw ft0, 124(s1) ; LP64-NEXT:flw ft0, 12(sp) # 4-byte Folded Reload @@ -915,7 +915,7 @@ define void @caller() nounwind { ; ILP32F-NEXT:flw fs5, 116(s1) ; ILP32F-NEXT:flw fs6, 120(s1) ; ILP32F-NEXT:flw fs7, 124(s1) -; ILP32F-NEXT:call callee +; ILP32F-NEXT:call callee@plt ; ILP32F-NEXT:fsw fs7, 124(s1) ; ILP32F-NEXT:fsw fs6, 120(s1) ; ILP32F-NEXT:fsw fs5, 116(s1) @@ -1058,7 +1058,7 @@ define void @caller() nounwind { ; LP64F-NEXT:flw fs5, 116(s1) ; LP64F-NEXT:flw fs6, 120(s1) ; LP64F-NEXT:flw fs7, 124(s1) -; LP64F-NEXT:call callee +; LP64F-NEXT:call callee@plt ; LP64F-NEXT:fsw fs7, 124(s1) ; LP64F-NEXT:fsw fs6, 120(s1) ; LP64F-NEXT:fsw fs5, 116(s1) @@ -1201,7 +1201,7 @@ define void @caller() nounwind { ; ILP32D-NEXT:flw fs5, 116(s1) ; ILP32D-NEXT:flw fs6, 120(s1) ; ILP32D-NEXT:flw fs7, 124(s1) -; ILP32D-NEXT:call callee +; ILP32D-NEXT:call callee@plt ; ILP32D-NEXT:fsw fs7, 124(s1) ; ILP32D-NEXT:fsw fs6, 120(s1) ; ILP32D-NEXT:fsw fs5, 116(s1) @@ -1344,7 +1344,7 @@ define void @caller() nounwind { ; LP64D-NEXT:flw fs5, 116(s1) ; LP64D-NEXT:flw fs6, 120(s1) ; LP64D-NEXT:flw fs7, 124(s1) -; LP64D-NEXT:call callee +; LP64D-NEXT:call callee@plt ; LP64D-NEXT:fsw fs7, 124(s1) ; LP64D-NEXT:fsw fs6, 120(s1) ; LP64D-NEXT:fsw fs5, 116(s1) diff --git a/llvm/test/CodeGen/RISCV/callee-saved-fpr64s.ll b/llvm/test/CodeGen/RISCV/callee-saved-fpr64s.ll index efd0455a821d..e18cb5953492 100644 --- a/llvm/test/CodeGen/RISCV/callee-saved-fpr64s.ll +++ b/llvm/test/CodeGen/RISCV/callee-saved-fpr64s.ll @@ -433,7 +433,7 @@ define void @caller() nounwind { ; ILP32-NEXT:fsd ft0, 8(sp) # 8-byte Folded Spill ; ILP32-NEXT:fld ft0, 248(s1) ; ILP32-NEXT:fsd ft0, 0(sp) # 8-byte Folded Spill -; ILP32-NEXT:call callee +; ILP32-NEXT:call callee@plt ; ILP32-NEXT:fld ft0, 0(sp) # 8-byte Folded Reload ; ILP32-NEXT:fsd ft0, 248(s1) ; ILP32-NEXT:fld ft0, 8(sp) # 8-byte Folded Reload @@ -576,7 +576,7 @@ define void @caller() nounwind { ; LP64-NEXT:fsd ft0, 16(sp) # 8-byte Folded Spill ; LP64-NEXT:fld ft0, 248(s1) ; LP64-NEXT:fsd ft0, 8(sp) # 8-byte Folded Spill -; LP64-NEXT:call callee +; LP64-NEXT:call callee@plt ; LP64-NEXT:fld ft0, 8(sp) # 8-byte Folded Reload ; LP64-NEXT:fsd ft0, 248(s1) ; LP64-NEXT:fld ft0, 16(sp) # 8-byte Folded
[llvm-branch-commits] [llvm] 141e45b - [RISCV] Optimize Branch Comparisons
Author: Sam Elliott Date: 2021-01-15T11:28:19Z New Revision: 141e45b99ca09235b985504e8108dbb3cf210fbd URL: https://github.com/llvm/llvm-project/commit/141e45b99ca09235b985504e8108dbb3cf210fbd DIFF: https://github.com/llvm/llvm-project/commit/141e45b99ca09235b985504e8108dbb3cf210fbd.diff LOG: [RISCV] Optimize Branch Comparisons I noticed in D94450 that there were quite a few places where we generate the sequence: ``` xN <- comparison ... xN <- xor xN, 1 bnez xN, symbol ``` Given we know the XOR will be used by BRCOND, which only looks at the lowest bit, I think we can remove the XOR and just invert the branch condition in these cases? The case mostly seems to come up in floating point tests, where there is often more logic to combine the results of multiple SETCCs, rather than a single (BRCOND (SETCC ...) ...). Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D94535 Added: Modified: llvm/lib/Target/RISCV/RISCVInstrInfo.td llvm/test/CodeGen/RISCV/double-br-fcmp.ll llvm/test/CodeGen/RISCV/float-br-fcmp.ll llvm/test/CodeGen/RISCV/half-br-fcmp.ll Removed: diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 4aee8ae39cc2..6b0967e12736 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -966,9 +966,13 @@ def : BccSwapPat; def : BccSwapPat; def : BccSwapPat; -// An extra pattern is needed for a brcond without a setcc (i.e. where the +// Extra patterns are needed for a brcond without a setcc (i.e. where the // condition was calculated elsewhere). def : Pat<(brcond GPR:$cond, bb:$imm12), (BNE GPR:$cond, X0, bb:$imm12)>; +// In this pattern, the `(xor $cond, 1)` functions like (boolean) `not`, as the +// `brcond` only uses the lowest bit. +def : Pat<(brcond (XLenVT (xor GPR:$cond, 1)), bb:$imm12), + (BEQ GPR:$cond, X0, bb:$imm12)>; let isBarrier = 1, isBranch = 1, isTerminator = 1 in def PseudoBR : Pseudo<(outs), (ins simm21_lsb0_jal:$imm20), [(br bb:$imm20)]>, diff --git a/llvm/test/CodeGen/RISCV/double-br-fcmp.ll b/llvm/test/CodeGen/RISCV/double-br-fcmp.ll index 94744a22364d..6336d7b12ef3 100644 --- a/llvm/test/CodeGen/RISCV/double-br-fcmp.ll +++ b/llvm/test/CodeGen/RISCV/double-br-fcmp.ll @@ -100,8 +100,7 @@ define void @br_fcmp_oeq_alt(double %a, double %b) nounwind { ; RV32IFD-NEXT:sw a1, 4(sp) ; RV32IFD-NEXT:fld ft1, 0(sp) ; RV32IFD-NEXT:feq.d a0, ft1, ft0 -; RV32IFD-NEXT:xori a0, a0, 1 -; RV32IFD-NEXT:beqz a0, .LBB2_2 +; RV32IFD-NEXT:bnez a0, .LBB2_2 ; RV32IFD-NEXT: # %bb.1: # %if.else ; RV32IFD-NEXT:lw ra, 12(sp) # 4-byte Folded Reload ; RV32IFD-NEXT:addi sp, sp, 16 @@ -116,8 +115,7 @@ define void @br_fcmp_oeq_alt(double %a, double %b) nounwind { ; RV64IFD-NEXT:fmv.d.x ft0, a1 ; RV64IFD-NEXT:fmv.d.x ft1, a0 ; RV64IFD-NEXT:feq.d a0, ft1, ft0 -; RV64IFD-NEXT:xori a0, a0, 1 -; RV64IFD-NEXT:beqz a0, .LBB2_2 +; RV64IFD-NEXT:bnez a0, .LBB2_2 ; RV64IFD-NEXT: # %bb.1: # %if.else ; RV64IFD-NEXT:ld ra, 8(sp) # 8-byte Folded Reload ; RV64IFD-NEXT:addi sp, sp, 16 @@ -460,8 +458,7 @@ define void @br_fcmp_ugt(double %a, double %b) nounwind { ; RV32IFD-NEXT:sw a1, 4(sp) ; RV32IFD-NEXT:fld ft1, 0(sp) ; RV32IFD-NEXT:fle.d a0, ft1, ft0 -; RV32IFD-NEXT:xori a0, a0, 1 -; RV32IFD-NEXT:bnez a0, .LBB10_2 +; RV32IFD-NEXT:beqz a0, .LBB10_2 ; RV32IFD-NEXT: # %bb.1: # %if.else ; RV32IFD-NEXT:lw ra, 12(sp) # 4-byte Folded Reload ; RV32IFD-NEXT:addi sp, sp, 16 @@ -476,8 +473,7 @@ define void @br_fcmp_ugt(double %a, double %b) nounwind { ; RV64IFD-NEXT:fmv.d.x ft0, a1 ; RV64IFD-NEXT:fmv.d.x ft1, a0 ; RV64IFD-NEXT:fle.d a0, ft1, ft0 -; RV64IFD-NEXT:xori a0, a0, 1 -; RV64IFD-NEXT:bnez a0, .LBB10_2 +; RV64IFD-NEXT:beqz a0, .LBB10_2 ; RV64IFD-NEXT: # %bb.1: # %if.else ; RV64IFD-NEXT:ld ra, 8(sp) # 8-byte Folded Reload ; RV64IFD-NEXT:addi sp, sp, 16 @@ -505,8 +501,7 @@ define void @br_fcmp_uge(double %a, double %b) nounwind { ; RV32IFD-NEXT:sw a1, 4(sp) ; RV32IFD-NEXT:fld ft1, 0(sp) ; RV32IFD-NEXT:flt.d a0, ft1, ft0 -; RV32IFD-NEXT:xori a0, a0, 1 -; RV32IFD-NEXT:bnez a0, .LBB11_2 +; RV32IFD-NEXT:beqz a0, .LBB11_2 ; RV32IFD-NEXT: # %bb.1: # %if.else ; RV32IFD-NEXT:lw ra, 12(sp) # 4-byte Folded Reload ; RV32IFD-NEXT:addi sp, sp, 16 @@ -521,8 +516,7 @@ define void @br_fcmp_uge(double %a, double %b) nounwind { ; RV64IFD-NEXT:fmv.d.x ft0, a1 ; RV64IFD-NEXT:fmv.d.x ft1, a0 ; RV64IFD-NEXT:flt.d a0, ft1, ft0 -; RV64IFD-NEXT:xori a0, a0, 1 -; RV64IFD-NEXT:bnez a0, .LBB11_2 +; RV64IFD-NEXT:beqz a0, .LBB11_2 ; RV64IFD-NEXT: # %bb.1: # %if.else ; RV64IFD-NEXT:ld ra, 8(sp) # 8-byte Folded Reload ; RV64IFD-NEXT:addi sp, sp, 16 @@ -550,8 +544,7 @@ define
[llvm-branch-commits] [llvm] bf1aa5d - [RISCV][NFC] Fix order of parameters in cmov ge/le tests
Author: Michael Munday Date: 2021-01-15T15:35:13Z New Revision: bf1aa5db5c76d187df8dfef28bc5b8889fb53c4b URL: https://github.com/llvm/llvm-project/commit/bf1aa5db5c76d187df8dfef28bc5b8889fb53c4b DIFF: https://github.com/llvm/llvm-project/commit/bf1aa5db5c76d187df8dfef28bc5b8889fb53c4b.diff LOG: [RISCV][NFC] Fix order of parameters in cmov ge/le tests The first parameter should be selected if the condition is true and the last parameter if the condition is false. Prior to this change it was the other way round which was confusing. Differential Revision: https://reviews.llvm.org/D94729 Added: Modified: llvm/test/CodeGen/RISCV/rv32Zbt.ll llvm/test/CodeGen/RISCV/rv64Zbt.ll Removed: diff --git a/llvm/test/CodeGen/RISCV/rv32Zbt.ll b/llvm/test/CodeGen/RISCV/rv32Zbt.ll index 7011698c13a9..279c39344b7d 100644 --- a/llvm/test/CodeGen/RISCV/rv32Zbt.ll +++ b/llvm/test/CodeGen/RISCV/rv32Zbt.ll @@ -91,30 +91,27 @@ define i32 @cmov_sle_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { ; RV32I: # %bb.0: ; RV32I-NEXT:bge a2, a1, .LBB3_2 ; RV32I-NEXT: # %bb.1: -; RV32I-NEXT:mv a3, a0 -; RV32I-NEXT: .LBB3_2: ; RV32I-NEXT:mv a0, a3 +; RV32I-NEXT: .LBB3_2: ; RV32I-NEXT:ret ; ; RV32IB-LABEL: cmov_sle_i32: ; RV32IB: # %bb.0: ; RV32IB-NEXT:bge a2, a1, .LBB3_2 ; RV32IB-NEXT: # %bb.1: -; RV32IB-NEXT:mv a3, a0 -; RV32IB-NEXT: .LBB3_2: ; RV32IB-NEXT:mv a0, a3 +; RV32IB-NEXT: .LBB3_2: ; RV32IB-NEXT:ret ; ; RV32IBT-LABEL: cmov_sle_i32: ; RV32IBT: # %bb.0: ; RV32IBT-NEXT:bge a2, a1, .LBB3_2 ; RV32IBT-NEXT: # %bb.1: -; RV32IBT-NEXT:mv a3, a0 -; RV32IBT-NEXT: .LBB3_2: ; RV32IBT-NEXT:mv a0, a3 +; RV32IBT-NEXT: .LBB3_2: ; RV32IBT-NEXT:ret %tobool = icmp sle i32 %b, %c - %cond = select i1 %tobool, i32 %d, i32 %a + %cond = select i1 %tobool, i32 %a, i32 %d ret i32 %cond } @@ -123,30 +120,27 @@ define i32 @cmov_sge_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { ; RV32I: # %bb.0: ; RV32I-NEXT:bge a1, a2, .LBB4_2 ; RV32I-NEXT: # %bb.1: -; RV32I-NEXT:mv a3, a0 -; RV32I-NEXT: .LBB4_2: ; RV32I-NEXT:mv a0, a3 +; RV32I-NEXT: .LBB4_2: ; RV32I-NEXT:ret ; ; RV32IB-LABEL: cmov_sge_i32: ; RV32IB: # %bb.0: ; RV32IB-NEXT:bge a1, a2, .LBB4_2 ; RV32IB-NEXT: # %bb.1: -; RV32IB-NEXT:mv a3, a0 -; RV32IB-NEXT: .LBB4_2: ; RV32IB-NEXT:mv a0, a3 +; RV32IB-NEXT: .LBB4_2: ; RV32IB-NEXT:ret ; ; RV32IBT-LABEL: cmov_sge_i32: ; RV32IBT: # %bb.0: ; RV32IBT-NEXT:bge a1, a2, .LBB4_2 ; RV32IBT-NEXT: # %bb.1: -; RV32IBT-NEXT:mv a3, a0 -; RV32IBT-NEXT: .LBB4_2: ; RV32IBT-NEXT:mv a0, a3 +; RV32IBT-NEXT: .LBB4_2: ; RV32IBT-NEXT:ret %tobool = icmp sge i32 %b, %c - %cond = select i1 %tobool, i32 %d, i32 %a + %cond = select i1 %tobool, i32 %a, i32 %d ret i32 %cond } @@ -155,30 +149,27 @@ define i32 @cmov_ule_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { ; RV32I: # %bb.0: ; RV32I-NEXT:bgeu a2, a1, .LBB5_2 ; RV32I-NEXT: # %bb.1: -; RV32I-NEXT:mv a3, a0 -; RV32I-NEXT: .LBB5_2: ; RV32I-NEXT:mv a0, a3 +; RV32I-NEXT: .LBB5_2: ; RV32I-NEXT:ret ; ; RV32IB-LABEL: cmov_ule_i32: ; RV32IB: # %bb.0: ; RV32IB-NEXT:bgeu a2, a1, .LBB5_2 ; RV32IB-NEXT: # %bb.1: -; RV32IB-NEXT:mv a3, a0 -; RV32IB-NEXT: .LBB5_2: ; RV32IB-NEXT:mv a0, a3 +; RV32IB-NEXT: .LBB5_2: ; RV32IB-NEXT:ret ; ; RV32IBT-LABEL: cmov_ule_i32: ; RV32IBT: # %bb.0: ; RV32IBT-NEXT:bgeu a2, a1, .LBB5_2 ; RV32IBT-NEXT: # %bb.1: -; RV32IBT-NEXT:mv a3, a0 -; RV32IBT-NEXT: .LBB5_2: ; RV32IBT-NEXT:mv a0, a3 +; RV32IBT-NEXT: .LBB5_2: ; RV32IBT-NEXT:ret %tobool = icmp ule i32 %b, %c - %cond = select i1 %tobool, i32 %d, i32 %a + %cond = select i1 %tobool, i32 %a, i32 %d ret i32 %cond } @@ -187,30 +178,27 @@ define i32 @cmov_uge_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { ; RV32I: # %bb.0: ; RV32I-NEXT:bgeu a1, a2, .LBB6_2 ; RV32I-NEXT: # %bb.1: -; RV32I-NEXT:mv a3, a0 -; RV32I-NEXT: .LBB6_2: ; RV32I-NEXT:mv a0, a3 +; RV32I-NEXT: .LBB6_2: ; RV32I-NEXT:ret ; ; RV32IB-LABEL: cmov_uge_i32: ; RV32IB: # %bb.0: ; RV32IB-NEXT:bgeu a1, a2, .LBB6_2 ; RV32IB-NEXT: # %bb.1: -; RV32IB-NEXT:mv a3, a0 -; RV32IB-NEXT: .LBB6_2: ; RV32IB-NEXT:mv a0, a3 +; RV32IB-NEXT: .LBB6_2: ; RV32IB-NEXT:ret ; ; RV32IBT-LABEL: cmov_uge_i32: ; RV32IBT: # %bb.0: ; RV32IBT-NEXT:bgeu a1, a2, .LBB6_2 ; RV32IBT-NEXT: # %bb.1: -; RV32IBT-NEXT:mv a3, a0 -; RV32IBT-NEXT: .LBB6_2: ; RV32IBT-NEXT:mv a0, a3 +; RV32IBT-NEXT: .LBB6_2: ; RV32IBT-NEXT:ret %tobool = icmp uge i32 %b, %c - %cond = select i1 %tobool, i32 %d, i32 %a + %cond = select i1 %tobool, i32 %a, i32 %d ret i32 %cond } @@ -259,11 +247,9 @@ define i64 @cmov_sle_i64(i64 %a, i64 %b, i64 %c, i64 %d)
[llvm-branch-commits] [llvm] b42ff9f - [RISCV][NFC] Increase test coverage of Zbt extension
Author: Michael Munday Date: 2021-01-18T17:30:35Z New Revision: b42ff9fb038206c7967e22ceef2c7ea8275dc198 URL: https://github.com/llvm/llvm-project/commit/b42ff9fb038206c7967e22ceef2c7ea8275dc198 DIFF: https://github.com/llvm/llvm-project/commit/b42ff9fb038206c7967e22ceef2c7ea8275dc198.diff LOG: [RISCV][NFC] Increase test coverage of Zbt extension Add Zbt (ternary) extension code generation to the select lowering tests since it can have a significant impact on how select is lowered. While we are here make the neg-abs commands more consistent with the other tests. Reviewed By: lenary Differential Revision: https://reviews.llvm.org/D94798 Added: llvm/test/CodeGen/RISCV/select-bare.ll Modified: llvm/test/CodeGen/RISCV/neg-abs.ll llvm/test/CodeGen/RISCV/select-and.ll llvm/test/CodeGen/RISCV/select-cc.ll llvm/test/CodeGen/RISCV/select-const.ll llvm/test/CodeGen/RISCV/select-optimize-multiple.ll llvm/test/CodeGen/RISCV/select-optimize-multiple.mir llvm/test/CodeGen/RISCV/select-or.ll Removed: llvm/test/CodeGen/RISCV/bare-select.ll diff --git a/llvm/test/CodeGen/RISCV/neg-abs.ll b/llvm/test/CodeGen/RISCV/neg-abs.ll index b5e5d2ae31490..f2e75792a9170 100644 --- a/llvm/test/CodeGen/RISCV/neg-abs.ll +++ b/llvm/test/CodeGen/RISCV/neg-abs.ll @@ -1,43 +1,77 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc < %s -verify-machineinstrs -mtriple=riscv32-unknown-unknown | FileCheck %s --check-prefix=RV32 -; RUN: llc < %s -verify-machineinstrs -mtriple=riscv64-unknown-unknown | FileCheck %s --check-prefix=RV64 +; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ +; RUN: | FileCheck %s --check-prefix=RV32I +; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -verify-machineinstrs < %s \ +; RUN: | FileCheck %s --check-prefix=RV32IBT +; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ +; RUN: | FileCheck %s --check-prefix=RV64I +; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbt -verify-machineinstrs < %s \ +; RUN: | FileCheck %s --check-prefix=RV64IBT declare i32 @llvm.abs.i32(i32, i1 immarg) declare i64 @llvm.abs.i64(i64, i1 immarg) define i32 @neg_abs32(i32 %x) { -; RV32-LABEL: neg_abs32: -; RV32: # %bb.0: -; RV32-NEXT:srai a1, a0, 31 -; RV32-NEXT:xor a0, a0, a1 -; RV32-NEXT:sub a0, a1, a0 -; RV32-NEXT:ret +; RV32I-LABEL: neg_abs32: +; RV32I: # %bb.0: +; RV32I-NEXT:srai a1, a0, 31 +; RV32I-NEXT:xor a0, a0, a1 +; RV32I-NEXT:sub a0, a1, a0 +; RV32I-NEXT:ret ; -; RV64-LABEL: neg_abs32: -; RV64: # %bb.0: -; RV64-NEXT:sraiw a1, a0, 31 -; RV64-NEXT:xor a0, a0, a1 -; RV64-NEXT:subw a0, a1, a0 -; RV64-NEXT:ret +; RV32IBT-LABEL: neg_abs32: +; RV32IBT: # %bb.0: +; RV32IBT-NEXT:srai a1, a0, 31 +; RV32IBT-NEXT:xor a0, a0, a1 +; RV32IBT-NEXT:sub a0, a1, a0 +; RV32IBT-NEXT:ret +; +; RV64I-LABEL: neg_abs32: +; RV64I: # %bb.0: +; RV64I-NEXT:sraiw a1, a0, 31 +; RV64I-NEXT:xor a0, a0, a1 +; RV64I-NEXT:subw a0, a1, a0 +; RV64I-NEXT:ret +; +; RV64IBT-LABEL: neg_abs32: +; RV64IBT: # %bb.0: +; RV64IBT-NEXT:sraiw a1, a0, 31 +; RV64IBT-NEXT:xor a0, a0, a1 +; RV64IBT-NEXT:subw a0, a1, a0 +; RV64IBT-NEXT:ret %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true) %neg = sub nsw i32 0, %abs ret i32 %neg } define i32 @select_neg_abs32(i32 %x) { -; RV32-LABEL: select_neg_abs32: -; RV32: # %bb.0: -; RV32-NEXT:srai a1, a0, 31 -; RV32-NEXT:xor a0, a0, a1 -; RV32-NEXT:sub a0, a1, a0 -; RV32-NEXT:ret +; RV32I-LABEL: select_neg_abs32: +; RV32I: # %bb.0: +; RV32I-NEXT:srai a1, a0, 31 +; RV32I-NEXT:xor a0, a0, a1 +; RV32I-NEXT:sub a0, a1, a0 +; RV32I-NEXT:ret +; +; RV32IBT-LABEL: select_neg_abs32: +; RV32IBT: # %bb.0: +; RV32IBT-NEXT:srai a1, a0, 31 +; RV32IBT-NEXT:xor a0, a0, a1 +; RV32IBT-NEXT:sub a0, a1, a0 +; RV32IBT-NEXT:ret +; +; RV64I-LABEL: select_neg_abs32: +; RV64I: # %bb.0: +; RV64I-NEXT:sraiw a1, a0, 31 +; RV64I-NEXT:xor a0, a0, a1 +; RV64I-NEXT:subw a0, a1, a0 +; RV64I-NEXT:ret ; -; RV64-LABEL: select_neg_abs32: -; RV64: # %bb.0: -; RV64-NEXT:sraiw a1, a0, 31 -; RV64-NEXT:xor a0, a0, a1 -; RV64-NEXT:subw a0, a1, a0 -; RV64-NEXT:ret +; RV64IBT-LABEL: select_neg_abs32: +; RV64IBT: # %bb.0: +; RV64IBT-NEXT:sraiw a1, a0, 31 +; RV64IBT-NEXT:xor a0, a0, a1 +; RV64IBT-NEXT:subw a0, a1, a0 +; RV64IBT-NEXT:ret %1 = icmp slt i32 %x, 0 %2 = sub nsw i32 0, %x %3 = select i1 %1, i32 %x, i32 %2 @@ -45,46 +79,82 @@ define i32 @select_neg_abs32(i32 %x) { } define i64 @neg_abs64(i64 %x) { -; RV32-LABEL: neg_abs64: -; RV32: # %bb.0: -; RV32-NEXT:srai a2, a1, 31 -; RV32-NEXT:xor a0, a0, a2 -; RV32-NEXT:sltu a3, a2, a0 -; RV32-NEXT:xor a1, a1, a2 -; RV32-N
[llvm-branch-commits] [llvm] e2d3d50 - [RISCV][NFC] Add additional cmov tests
Author: Michael Munday Date: 2021-01-04T16:01:40Z New Revision: e2d3d501ef8b49eb8990dd3556948373b023cd48 URL: https://github.com/llvm/llvm-project/commit/e2d3d501ef8b49eb8990dd3556948373b023cd48 DIFF: https://github.com/llvm/llvm-project/commit/e2d3d501ef8b49eb8990dd3556948373b023cd48.diff LOG: [RISCV][NFC] Add additional cmov tests One or more cmov instructions could be generated for these functions when the Zbt extension is present. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D93768 Added: Modified: llvm/test/CodeGen/RISCV/rv32Zbt.ll llvm/test/CodeGen/RISCV/rv64Zbt.ll Removed: diff --git a/llvm/test/CodeGen/RISCV/rv32Zbt.ll b/llvm/test/CodeGen/RISCV/rv32Zbt.ll index 68501812f2c6..7011698c13a9 100644 --- a/llvm/test/CodeGen/RISCV/rv32Zbt.ll +++ b/llvm/test/CodeGen/RISCV/rv32Zbt.ll @@ -86,15 +86,143 @@ define i32 @cmov_i32(i32 %a, i32 %b, i32 %c) nounwind { ret i32 %cond } +define i32 @cmov_sle_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { +; RV32I-LABEL: cmov_sle_i32: +; RV32I: # %bb.0: +; RV32I-NEXT:bge a2, a1, .LBB3_2 +; RV32I-NEXT: # %bb.1: +; RV32I-NEXT:mv a3, a0 +; RV32I-NEXT: .LBB3_2: +; RV32I-NEXT:mv a0, a3 +; RV32I-NEXT:ret +; +; RV32IB-LABEL: cmov_sle_i32: +; RV32IB: # %bb.0: +; RV32IB-NEXT:bge a2, a1, .LBB3_2 +; RV32IB-NEXT: # %bb.1: +; RV32IB-NEXT:mv a3, a0 +; RV32IB-NEXT: .LBB3_2: +; RV32IB-NEXT:mv a0, a3 +; RV32IB-NEXT:ret +; +; RV32IBT-LABEL: cmov_sle_i32: +; RV32IBT: # %bb.0: +; RV32IBT-NEXT:bge a2, a1, .LBB3_2 +; RV32IBT-NEXT: # %bb.1: +; RV32IBT-NEXT:mv a3, a0 +; RV32IBT-NEXT: .LBB3_2: +; RV32IBT-NEXT:mv a0, a3 +; RV32IBT-NEXT:ret + %tobool = icmp sle i32 %b, %c + %cond = select i1 %tobool, i32 %d, i32 %a + ret i32 %cond +} + +define i32 @cmov_sge_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { +; RV32I-LABEL: cmov_sge_i32: +; RV32I: # %bb.0: +; RV32I-NEXT:bge a1, a2, .LBB4_2 +; RV32I-NEXT: # %bb.1: +; RV32I-NEXT:mv a3, a0 +; RV32I-NEXT: .LBB4_2: +; RV32I-NEXT:mv a0, a3 +; RV32I-NEXT:ret +; +; RV32IB-LABEL: cmov_sge_i32: +; RV32IB: # %bb.0: +; RV32IB-NEXT:bge a1, a2, .LBB4_2 +; RV32IB-NEXT: # %bb.1: +; RV32IB-NEXT:mv a3, a0 +; RV32IB-NEXT: .LBB4_2: +; RV32IB-NEXT:mv a0, a3 +; RV32IB-NEXT:ret +; +; RV32IBT-LABEL: cmov_sge_i32: +; RV32IBT: # %bb.0: +; RV32IBT-NEXT:bge a1, a2, .LBB4_2 +; RV32IBT-NEXT: # %bb.1: +; RV32IBT-NEXT:mv a3, a0 +; RV32IBT-NEXT: .LBB4_2: +; RV32IBT-NEXT:mv a0, a3 +; RV32IBT-NEXT:ret + %tobool = icmp sge i32 %b, %c + %cond = select i1 %tobool, i32 %d, i32 %a + ret i32 %cond +} + +define i32 @cmov_ule_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { +; RV32I-LABEL: cmov_ule_i32: +; RV32I: # %bb.0: +; RV32I-NEXT:bgeu a2, a1, .LBB5_2 +; RV32I-NEXT: # %bb.1: +; RV32I-NEXT:mv a3, a0 +; RV32I-NEXT: .LBB5_2: +; RV32I-NEXT:mv a0, a3 +; RV32I-NEXT:ret +; +; RV32IB-LABEL: cmov_ule_i32: +; RV32IB: # %bb.0: +; RV32IB-NEXT:bgeu a2, a1, .LBB5_2 +; RV32IB-NEXT: # %bb.1: +; RV32IB-NEXT:mv a3, a0 +; RV32IB-NEXT: .LBB5_2: +; RV32IB-NEXT:mv a0, a3 +; RV32IB-NEXT:ret +; +; RV32IBT-LABEL: cmov_ule_i32: +; RV32IBT: # %bb.0: +; RV32IBT-NEXT:bgeu a2, a1, .LBB5_2 +; RV32IBT-NEXT: # %bb.1: +; RV32IBT-NEXT:mv a3, a0 +; RV32IBT-NEXT: .LBB5_2: +; RV32IBT-NEXT:mv a0, a3 +; RV32IBT-NEXT:ret + %tobool = icmp ule i32 %b, %c + %cond = select i1 %tobool, i32 %d, i32 %a + ret i32 %cond +} + +define i32 @cmov_uge_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { +; RV32I-LABEL: cmov_uge_i32: +; RV32I: # %bb.0: +; RV32I-NEXT:bgeu a1, a2, .LBB6_2 +; RV32I-NEXT: # %bb.1: +; RV32I-NEXT:mv a3, a0 +; RV32I-NEXT: .LBB6_2: +; RV32I-NEXT:mv a0, a3 +; RV32I-NEXT:ret +; +; RV32IB-LABEL: cmov_uge_i32: +; RV32IB: # %bb.0: +; RV32IB-NEXT:bgeu a1, a2, .LBB6_2 +; RV32IB-NEXT: # %bb.1: +; RV32IB-NEXT:mv a3, a0 +; RV32IB-NEXT: .LBB6_2: +; RV32IB-NEXT:mv a0, a3 +; RV32IB-NEXT:ret +; +; RV32IBT-LABEL: cmov_uge_i32: +; RV32IBT: # %bb.0: +; RV32IBT-NEXT:bgeu a1, a2, .LBB6_2 +; RV32IBT-NEXT: # %bb.1: +; RV32IBT-NEXT:mv a3, a0 +; RV32IBT-NEXT: .LBB6_2: +; RV32IBT-NEXT:mv a0, a3 +; RV32IBT-NEXT:ret + %tobool = icmp uge i32 %b, %c + %cond = select i1 %tobool, i32 %d, i32 %a + ret i32 %cond +} + define i64 @cmov_i64(i64 %a, i64 %b, i64 %c) nounwind { ; RV32I-LABEL: cmov_i64: ; RV32I: # %bb.0: ; RV32I-NEXT:or a2, a2, a3 -; RV32I-NEXT:beqz a2, .LBB3_2 +; RV32I-NEXT:beqz a2, .LBB7_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT:mv a4, a0 ; RV32I-NEXT:mv a5, a1 -; RV32I-NEXT: .LBB3_2: +; RV32I-NEXT: .LBB7_2: ; RV32I-NEXT:mv a0, a4 ; RV32I-NEXT:mv a1, a5 ; RV32I-NEXT:ret @@ -117,6 +245,266 @@ define i64 @cmov_i64(i64 %a, i64 %b, i64 %c) nounwind { ret i6
[llvm-branch-commits] [llvm] 12406ad - [RISCV] Add (Proposed) Assembler Extend Pseudo-Instructions
Author: Sam Elliott Date: 2020-12-10T19:25:51Z New Revision: 12406ade0625ffa3939e2fa684293e02eb8791ff URL: https://github.com/llvm/llvm-project/commit/12406ade0625ffa3939e2fa684293e02eb8791ff DIFF: https://github.com/llvm/llvm-project/commit/12406ade0625ffa3939e2fa684293e02eb8791ff.diff LOG: [RISCV] Add (Proposed) Assembler Extend Pseudo-Instructions There is an in-progress proposal for the following pseudo-instructions in the assembler, to complement the existing `sext.w` rv64i instruction: - sext.b - sext.h - zext.b - zext.h - zext.w The `.b` and `.h` variants are available with rv32i and rv64i, and `zext.w` is only available with `rv64i`. These are implemented primarily as pseudo-instructions, as these instructions expand to multiple real instructions. In the case of `zext.b`, this expands to a single rv32/64i instruction, so it is implemented with an InstAlias (like `sext.w` is on rv64i). The proposal is available here: https://github.com/riscv/riscv-asm-manual/pull/61 Reviewed By: asb Differential Revision: https://reviews.llvm.org/D92793 Added: Modified: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp llvm/lib/Target/RISCV/RISCV.td llvm/lib/Target/RISCV/RISCVInstrInfo.td llvm/lib/Target/RISCV/RISCVInstrInfoB.td llvm/test/CodeGen/RISCV/alu8.ll llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll llvm/test/CodeGen/RISCV/atomic-rmw.ll llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll llvm/test/CodeGen/RISCV/calling-conv-sext-zext.ll llvm/test/CodeGen/RISCV/rv32Zbbp.ll llvm/test/CodeGen/RISCV/rv64Zbbp.ll llvm/test/CodeGen/RISCV/sext-zext-trunc.ll llvm/test/MC/RISCV/rv32i-aliases-invalid.s llvm/test/MC/RISCV/rv32i-aliases-valid.s llvm/test/MC/RISCV/rv64i-aliases-valid.s Removed: diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 768b34ad45f1..aa483041e635 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -124,6 +124,10 @@ class RISCVAsmParser : public MCTargetAsmParser { void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, MCStreamer &Out, bool HasTmpReg); + // Helper to emit pseudo sign/zero extend instruction. + void emitPseudoExtend(MCInst &Inst, bool SignExtend, int64_t Width, +SMLoc IDLoc, MCStreamer &Out); + // Checks that a PseudoAddTPRel is using x4/tp in its second input operand. // Enforcing this using a restricted register class for the second input // operand of PseudoAddTPRel results in a poor diagnostic due to the fact @@ -2269,6 +2273,35 @@ void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, Opcode, IDLoc, Out); } +void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend, + int64_t Width, SMLoc IDLoc, + MCStreamer &Out) { + // The sign/zero extend pseudo-instruction does two shifts, with the shift + // amounts dependent on the XLEN. + // + // The expansion looks like this + // + //SLLI rd, rs, XLEN - Width + //SR[A|R]I rd, rd, XLEN - Width + MCOperand DestReg = Inst.getOperand(0); + MCOperand SourceReg = Inst.getOperand(1); + + unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI; + int64_t ShAmt = (isRV64() ? 64 : 32) - Width; + + assert(ShAmt > 0 && "Shift amount must be non-zero."); + + emitToStreamer(Out, MCInstBuilder(RISCV::SLLI) + .addOperand(DestReg) + .addOperand(SourceReg) + .addImm(ShAmt)); + + emitToStreamer(Out, MCInstBuilder(SecondOpcode) + .addOperand(DestReg) + .addOperand(DestReg) + .addImm(ShAmt)); +} + bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands) { assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"); @@ -2431,6 +2464,18 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, if (checkPseudoAddTPRel(Inst, Operands)) return true; break; + case RISCV::PseudoSEXT_B: +emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out); +return false; + case RISCV::PseudoSEXT_H: +emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/16, IDLoc, Out); +return false; + case RISCV::PseudoZEXT_H: +emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/16, IDLoc, Out); +return false; + case RISCV::PseudoZEXT_W: +emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/32, IDLoc, Out); +return false; } emitToStreamer(Out, Inst); di
[llvm-branch-commits] [llvm] b7901e4 - [RISCV][NFC] Fix Sext/Zext Tests
Author: Sam Elliott Date: 2020-12-10T20:10:29Z New Revision: b7901e4c1a2ef0de73f133d5ecc6abbc3f427bdc URL: https://github.com/llvm/llvm-project/commit/b7901e4c1a2ef0de73f133d5ecc6abbc3f427bdc DIFF: https://github.com/llvm/llvm-project/commit/b7901e4c1a2ef0de73f133d5ecc6abbc3f427bdc.diff LOG: [RISCV][NFC] Fix Sext/Zext Tests These were missed in a rebase of https://reviews.llvm.org/D92793 Added: Modified: llvm/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll llvm/test/CodeGen/RISCV/calling-conv-sext-zext.ll Removed: diff --git a/llvm/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll b/llvm/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll index c53b79913b1c..53bed26f448c 100644 --- a/llvm/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll +++ b/llvm/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll @@ -81,7 +81,7 @@ define i8 @test_cttz_i8(i8 %a) nounwind { ; RV32I: # %bb.0: ; RV32I-NEXT:addi sp, sp, -16 ; RV32I-NEXT:sw ra, 12(sp) # 4-byte Folded Spill -; RV32I-NEXT:andi a1, a0, 255 +; RV32I-NEXT:zext.b a1, a0 ; RV32I-NEXT:beqz a1, .LBB3_2 ; RV32I-NEXT: # %bb.1: # %cond.false ; RV32I-NEXT:addi a1, a0, -1 diff --git a/llvm/test/CodeGen/RISCV/calling-conv-sext-zext.ll b/llvm/test/CodeGen/RISCV/calling-conv-sext-zext.ll index ac060f9469ac..1d5db5e7a49a 100644 --- a/llvm/test/CodeGen/RISCV/calling-conv-sext-zext.ll +++ b/llvm/test/CodeGen/RISCV/calling-conv-sext-zext.ll @@ -122,7 +122,7 @@ define signext i32 @ret_callresult_uint8_as_anyint32() nounwind { define zeroext i8 @sint8_arg_to_uint8_ret(i8 signext %a) nounwind { ; RV32I-LABEL: sint8_arg_to_uint8_ret: ; RV32I: # %bb.0: -; RV32I-NEXT:andi a0, a0, 255 +; RV32I-NEXT:zext.b a0, a0 ; RV32I-NEXT:ret ret i8 %a } @@ -132,7 +132,7 @@ define void @pass_sint8_as_uint8(i8 signext %a) nounwind { ; RV32I: # %bb.0: ; RV32I-NEXT:addi sp, sp, -16 ; RV32I-NEXT:sw ra, 12(sp) # 4-byte Folded Spill -; RV32I-NEXT:andi a0, a0, 255 +; RV32I-NEXT:zext.b a0, a0 ; RV32I-NEXT:call receive_uint8@plt ; RV32I-NEXT:lw ra, 12(sp) # 4-byte Folded Reload ; RV32I-NEXT:addi sp, sp, 16 @@ -149,7 +149,7 @@ define zeroext i8 @ret_callresult_sint8_as_uint8() nounwind { ; RV32I-NEXT:addi sp, sp, -16 ; RV32I-NEXT:sw ra, 12(sp) # 4-byte Folded Spill ; RV32I-NEXT:call return_sint8@plt -; RV32I-NEXT:andi a0, a0, 255 +; RV32I-NEXT:zext.b a0, a0 ; RV32I-NEXT:lw ra, 12(sp) # 4-byte Folded Reload ; RV32I-NEXT:addi sp, sp, 16 ; RV32I-NEXT:ret @@ -229,7 +229,7 @@ define signext i32 @ret_callresult_sint8_as_anyint32() nounwind { define zeroext i8 @anyint32_arg_to_uint8_ret(i32 signext %a) nounwind { ; RV32I-LABEL: anyint32_arg_to_uint8_ret: ; RV32I: # %bb.0: -; RV32I-NEXT:andi a0, a0, 255 +; RV32I-NEXT:zext.b a0, a0 ; RV32I-NEXT:ret %1 = trunc i32 %a to i8 ret i8 %1 @@ -240,7 +240,7 @@ define void @pass_anyint32_as_uint8(i32 signext %a) nounwind { ; RV32I: # %bb.0: ; RV32I-NEXT:addi sp, sp, -16 ; RV32I-NEXT:sw ra, 12(sp) # 4-byte Folded Spill -; RV32I-NEXT:andi a0, a0, 255 +; RV32I-NEXT:zext.b a0, a0 ; RV32I-NEXT:call receive_uint8@plt ; RV32I-NEXT:lw ra, 12(sp) # 4-byte Folded Reload ; RV32I-NEXT:addi sp, sp, 16 @@ -258,7 +258,7 @@ define zeroext i8 @ret_callresult_anyint32_as_uint8() nounwind { ; RV32I-NEXT:addi sp, sp, -16 ; RV32I-NEXT:sw ra, 12(sp) # 4-byte Folded Spill ; RV32I-NEXT:call return_anyint32@plt -; RV32I-NEXT:andi a0, a0, 255 +; RV32I-NEXT:zext.b a0, a0 ; RV32I-NEXT:lw ra, 12(sp) # 4-byte Folded Reload ; RV32I-NEXT:addi sp, sp, 16 ; RV32I-NEXT:ret ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 5cfd30a - [RISCV] Add Clang and LLVM Release Notes
Author: Sam Elliott Date: 2020-02-26T18:19:07Z New Revision: 5cfd30add460640264c7d88c4d837a2d4e0ae7b1 URL: https://github.com/llvm/llvm-project/commit/5cfd30add460640264c7d88c4d837a2d4e0ae7b1 DIFF: https://github.com/llvm/llvm-project/commit/5cfd30add460640264c7d88c4d837a2d4e0ae7b1.diff LOG: [RISCV] Add Clang and LLVM Release Notes Added: Modified: clang/docs/ReleaseNotes.rst llvm/docs/ReleaseNotes.rst Removed: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b160588b22c5..c9d0461b65aa 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -122,6 +122,9 @@ Non-comprehensive list of changes in this release * For the WebAssembly target, the ``wasm-opt`` tool will now be run if it is found in the PATH, which can reduce code size. +* For the RISC-V target, floating point registers can now be used in inline + assembly constraints. + New Compiler Flags -- @@ -141,6 +144,13 @@ New Compiler Flags please let us know if you encounter a situation where you need to specify this flag for correct program behavior. +- The `-ffixed-xX` flags now work on RISC-V. These reserve the corresponding + general-purpose registers. + +- RISC-V has added `-mcmodel=medany` and `-mcmodel=medlow` as aliases for + `-mcmodel=small` and `-mcmodel=medium` respectively. Preprocessor definitions + for `__riscv_cmodel_medlow` and `__riscv_cmodel_medany` have been corrected. + Deprecated Compiler Flags - @@ -182,6 +192,12 @@ Modified Compiler Flags which is one level below ``-debug-info-kind=limited``. This option causes debug info for classes to be emitted only when a constructor is emitted. +- RISC-V now chooses a slightly diff erent sysroot path and defaults to using + compiler-rt if no GCC installation is detected. + +- RISC-V now supports multilibs in baremetal environments. This support does not + extend to supporting multilib aliases. + New Pragmas in Clang @@ -309,6 +325,11 @@ ABI Changes in Clang `-mabi=` when compiling for RISC-V, due to how extensible this architecture is. +- RISC-V now uses `target-abi` module metadata to encode the chosen psABI. This + ensures that the correct lowering will be done by LLVM when LTO is enabled. + +- An issue with lowering return types in the RISC-V ILP32D psABI has been fixed. + OpenMP Support in Clang --- diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 6ade99ab174f..69a055aeef63 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -252,6 +252,65 @@ Changes to the Windows Target * Fixed section relative relocations in .debug_frame in DWARF debug info +Changes to the RISC-V Target + + +New Features: +* The Machine Outliner has been enabled. +* Shrink-wrapping has been enabled. +* The Machine Scheduler has been enabled and scheduler descriptions for the + Rocket micro-architecture have been added, covering both 32- and 64-bit Rocket + cores. +* This release lays the groundwork for enabling LTO in a future LLVM release. + In particular, LLVM now uses a new `target-abi` module metadata item to + represent the chosen RISC-V psABI variant. Frontends should add this module + flag to prevent ABI lowering problems when LTO is enabled in a future LLVM + release. +* Support has been added for assembling RVC HINT instructions. +* Added code lowering for half-precision floats. +* The `fscsr` and `frcsr` (`fssr`, `frsr`) obsolete aliases have been added to + the assembler for use in legacy code. +* The stack can now be realigned even when there are variable-sized objects in + the same frame. +* fastcc is now supported. +* llvm-objdump now supports `-M no-aliases` and `-M numeric` for altering the + dumped assembly. These match the behaviour of GNU objdump. + +Improvements: +* Trap and Debugtrap now lower to RISC-V-specific trap instructions. +* LLVM IR Inline assembly now supports using ABI register names and using + floating point registers in constraints. +* Stack Pointer adjustments have been changed to better match RISC-V's immediates. +* `ra` (`x1`) can now be used as a callee-saved register. +* The assembler now suggests spelling corrections for unknown assembly + mnemonics. +* Stack offsets of greater than 32-bits are now accepted on RV64. +* Some variadic functions can now be tail-call optimised. +* We now custom-lower 32-bit arithmetic operations on RV64 to reduce + sign-extensions. + + +Bug Fixes: + +* There was an issue with register preservation after calls in interrupt + handlers, where some registers were marked as preserved even though they were + not being preserved by the call. This has been corrected, and now only + callee-saved registers are live over a function call in an interrupt handler + (jus
[llvm-branch-commits] [llvm] 7e3ebf3 - [RISCV] Update RISC-V Release Notes for LLVM
Author: Sam Elliott Date: 2020-02-27T13:14:57Z New Revision: 7e3ebf34eb03ddc5fefe8d4fb2ed62a195bcee0e URL: https://github.com/llvm/llvm-project/commit/7e3ebf34eb03ddc5fefe8d4fb2ed62a195bcee0e DIFF: https://github.com/llvm/llvm-project/commit/7e3ebf34eb03ddc5fefe8d4fb2ed62a195bcee0e.diff LOG: [RISCV] Update RISC-V Release Notes for LLVM This corrects some typos and clarifies some points. Added: Modified: llvm/docs/ReleaseNotes.rst Removed: diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index a788f8f60042..7ca74e37858e 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -260,8 +260,8 @@ Changes to the RISC-V Target New Features: -* The Machine Outliner has been enabled. -* Shrink-wrapping has been enabled. +* The Machine Outliner is now supported, but not enabled by default. +* Shrink-wrapping is now supported. * The Machine Scheduler has been enabled and scheduler descriptions for the Rocket micro-architecture have been added, covering both 32- and 64-bit Rocket cores. @@ -276,9 +276,12 @@ New Features: the assembler for use in legacy code. * The stack can now be realigned even when there are variable-sized objects in the same frame. -* fastcc is now supported. +* fastcc is now supported. This is a more efficient, unstandardised, calling + convention for calls to private leaf functions in the same IR module. * llvm-objdump now supports `-M no-aliases` and `-M numeric` for altering the - dumped assembly. These match the behaviour of GNU objdump. + dumped assembly. These match the behaviour of GNU objdump, respectively + disabling instruction aliases and printing the numeric register names rather + than the ABI register names. Improvements: * Trap and Debugtrap now lower to RISC-V-specific trap instructions. @@ -289,20 +292,19 @@ Improvements: * The assembler now suggests spelling corrections for unknown assembly mnemonics. * Stack offsets of greater than 32-bits are now accepted on RV64. -* Some variadic functions can now be tail-call optimised. -* We now custom-lower 32-bit arithmetic operations on RV64 to reduce - sign-extensions. - +* Variadic functions can now be tail-call optimised, as long as they do not use + stack memory for passing arguments. +* Code generation has been changed for 32-bit arithmetic operations on RV64 to + reduce sign-extensions. Bug Fixes: - * There was an issue with register preservation after calls in interrupt handlers, where some registers were marked as preserved even though they were not being preserved by the call. This has been corrected, and now only callee-saved registers are live over a function call in an interrupt handler (just like calls in regular functions). * Atomic instructions now only accept GPRs (plus an offset) in memory operands. -* Fixed some issues with evalutaion of relocations and fixups. +* Fixed some issues with evaluation of relocations and fixups. * The error messages around missing RISC-V extensions in the assembler have been improved. * The error messages around unsupported relocations have been improved. @@ -314,7 +316,10 @@ Bug Fixes: * RV64 no longer clears the upper bits when returning complex types from libcalls using the LP64 psABI. - +Compiler-RT: +* RISC-V (both 64-bit and 32-bit) is now supported by compiler-rt, allowing + crtbegin and crtend to be built. +* The Sanitizers now support 64-bit RISC-V on linux. Changes to the OCaml bindings - ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [RISCV][NFC] refactor CFI emitting (PR #114227)
https://github.com/lenary commented: This cleanup is going in a nice direction, I think. A few suggestions/questions below. https://github.com/llvm/llvm-project/pull/114227 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [RISCV][NFC] refactor CFI emitting (PR #114227)
@@ -27,6 +27,102 @@ using namespace llvm; +static unsigned getCaleeSavedRVVNumRegs(const Register &BaseReg) { + return RISCV::VRRegClass.contains(BaseReg) ? 1 + : RISCV::VRM2RegClass.contains(BaseReg) ? 2 + : RISCV::VRM4RegClass.contains(BaseReg) ? 4 + : 8; +} + +static MCRegister getRVVBaseRegister(const RISCVRegisterInfo &TRI, + const Register &Reg) { + MCRegister BaseReg = TRI.getSubReg(Reg, RISCV::sub_vrm1_0); + // If it's not a grouped vector register, it doesn't have subregister, so + // the base register is just itself. + if (BaseReg == RISCV::NoRegister) +BaseReg = Reg; + return BaseReg; +} + +namespace { + +struct CFIRestoreRegisterEmitter { + CFIRestoreRegisterEmitter(MachineFunction &, const RISCVSubtarget &) {}; + + void emit(MachineFunction &MF, MachineBasicBlock &MBB, +MachineBasicBlock::iterator MBBI, const RISCVRegisterInfo &RI, +const RISCVInstrInfo &TII, const DebugLoc &DL, +const CalleeSavedInfo &CS) const { +Register Reg = CS.getReg(); +unsigned CFIIndex = MF.addFrameInst( +MCCFIInstruction::createRestore(nullptr, RI.getDwarfRegNum(Reg, true))); +BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) +.addCFIIndex(CFIIndex) +.setMIFlag(MachineInstr::FrameDestroy); + } +}; + +class CFIStoreRegisterEmitter { + MachineFrameInfo &MFI; + +public: + CFIStoreRegisterEmitter(MachineFunction &MF, const RISCVSubtarget &) + : MFI{MF.getFrameInfo()} {}; + + void emit(MachineFunction &MF, MachineBasicBlock &MBB, +MachineBasicBlock::iterator MBBI, const RISCVRegisterInfo &RI, +const RISCVInstrInfo &TII, const DebugLoc &DL, +const CalleeSavedInfo &CS) const { +int FrameIdx = CS.getFrameIdx(); +int64_t Offset = MFI.getObjectOffset(FrameIdx); +Register Reg = CS.getReg(); +unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( +nullptr, RI.getDwarfRegNum(Reg, true), Offset)); +BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) +.addCFIIndex(CFIIndex) +.setMIFlag(MachineInstr::FrameSetup); + } +}; + +class CFIRestoreRVVRegisterEmitter { + const llvm::RISCVRegisterInfo *TRI; + +public: + CFIRestoreRVVRegisterEmitter(MachineFunction &, const RISCVSubtarget &STI) + : TRI{STI.getRegisterInfo()} {}; + + void emit(MachineFunction &MF, MachineBasicBlock &MBB, +MachineBasicBlock::iterator MBBI, const RISCVRegisterInfo &RI, +const RISCVInstrInfo &TII, const DebugLoc &DL, +const CalleeSavedInfo &CS) const { +MCRegister BaseReg = getRVVBaseRegister(*TRI, CS.getReg()); +unsigned NumRegs = getCaleeSavedRVVNumRegs(CS.getReg()); +for (unsigned i = 0; i < NumRegs; ++i) { + unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore( + nullptr, RI.getDwarfRegNum(BaseReg + i, true))); + BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlag(MachineInstr::FrameDestroy); +} + } +}; + +} // namespace + +template +void RISCVFrameLowering::emitCFIForCSI( +MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +const SmallVector &CSI) const { + MachineFunction *MF = MBB.getParent(); + const RISCVRegisterInfo *RI = STI.getRegisterInfo(); + const RISCVInstrInfo *TII = STI.getInstrInfo(); + DebugLoc DL = MBB.findDebugLoc(MBBI); + + Emitter E{*MF, STI}; + for (const auto &CS : CSI) +E.emit(*MF, MBB, MBBI, *RI, *TII, DL, CS); lenary wrote: I don't quite know why `*MF` needs to be passed into both the constructor and into `emit`? Would it not be simpler to just pass it into the constructor and cache the reference? https://github.com/llvm/llvm-project/pull/114227 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [RISCV][NFC] refactor CFI emitting (PR #114227)
@@ -27,6 +27,102 @@ using namespace llvm; +static unsigned getCaleeSavedRVVNumRegs(const Register &BaseReg) { + return RISCV::VRRegClass.contains(BaseReg) ? 1 + : RISCV::VRM2RegClass.contains(BaseReg) ? 2 + : RISCV::VRM4RegClass.contains(BaseReg) ? 4 + : 8; +} + +static MCRegister getRVVBaseRegister(const RISCVRegisterInfo &TRI, + const Register &Reg) { + MCRegister BaseReg = TRI.getSubReg(Reg, RISCV::sub_vrm1_0); + // If it's not a grouped vector register, it doesn't have subregister, so + // the base register is just itself. + if (BaseReg == RISCV::NoRegister) +BaseReg = Reg; + return BaseReg; +} + +namespace { + +struct CFIRestoreRegisterEmitter { + CFIRestoreRegisterEmitter(MachineFunction &, const RISCVSubtarget &) {}; + + void emit(MachineFunction &MF, MachineBasicBlock &MBB, +MachineBasicBlock::iterator MBBI, const RISCVRegisterInfo &RI, +const RISCVInstrInfo &TII, const DebugLoc &DL, +const CalleeSavedInfo &CS) const { +Register Reg = CS.getReg(); +unsigned CFIIndex = MF.addFrameInst( +MCCFIInstruction::createRestore(nullptr, RI.getDwarfRegNum(Reg, true))); +BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) +.addCFIIndex(CFIIndex) +.setMIFlag(MachineInstr::FrameDestroy); + } +}; + +class CFIStoreRegisterEmitter { lenary wrote: ```suggestion class CFISaveRegisterEmitter { ``` I think it would be clearer to use "Save" as the opposite of "Restore", rather than "Store" vs "Restore". https://github.com/llvm/llvm-project/pull/114227 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [RISCV][NFC] refactor CFI emitting (PR #114227)
@@ -1737,39 +1776,14 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI( for (auto &CS : RVVCSI) { // Insert the spill to the stack frame. int FI = CS.getFrameIdx(); lenary wrote: Is there a reason you didn't replace this loop with a call to `emitCFIforCSI` with a new `CFISaveRVVRegisterEmitter`? That would give a little better symmetry in those objects, even though it doesn't get rid of the calls to `emitCalleeSavedRVVPrologCFI` because of the other logic happening before this loop. https://github.com/llvm/llvm-project/pull/114227 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [RISCV][NFC] refactor CFI emitting (PR #114227)
@@ -27,6 +27,102 @@ using namespace llvm; +static unsigned getCaleeSavedRVVNumRegs(const Register &BaseReg) { + return RISCV::VRRegClass.contains(BaseReg) ? 1 + : RISCV::VRM2RegClass.contains(BaseReg) ? 2 + : RISCV::VRM4RegClass.contains(BaseReg) ? 4 + : 8; +} + +static MCRegister getRVVBaseRegister(const RISCVRegisterInfo &TRI, + const Register &Reg) { + MCRegister BaseReg = TRI.getSubReg(Reg, RISCV::sub_vrm1_0); + // If it's not a grouped vector register, it doesn't have subregister, so + // the base register is just itself. + if (BaseReg == RISCV::NoRegister) +BaseReg = Reg; + return BaseReg; +} + +namespace { + +struct CFIRestoreRegisterEmitter { + CFIRestoreRegisterEmitter(MachineFunction &, const RISCVSubtarget &) {}; + + void emit(MachineFunction &MF, MachineBasicBlock &MBB, +MachineBasicBlock::iterator MBBI, const RISCVRegisterInfo &RI, +const RISCVInstrInfo &TII, const DebugLoc &DL, +const CalleeSavedInfo &CS) const { +Register Reg = CS.getReg(); +unsigned CFIIndex = MF.addFrameInst( +MCCFIInstruction::createRestore(nullptr, RI.getDwarfRegNum(Reg, true))); +BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) +.addCFIIndex(CFIIndex) +.setMIFlag(MachineInstr::FrameDestroy); + } +}; + +class CFIStoreRegisterEmitter { + MachineFrameInfo &MFI; + +public: + CFIStoreRegisterEmitter(MachineFunction &MF, const RISCVSubtarget &) + : MFI{MF.getFrameInfo()} {}; + + void emit(MachineFunction &MF, MachineBasicBlock &MBB, +MachineBasicBlock::iterator MBBI, const RISCVRegisterInfo &RI, +const RISCVInstrInfo &TII, const DebugLoc &DL, +const CalleeSavedInfo &CS) const { +int FrameIdx = CS.getFrameIdx(); +int64_t Offset = MFI.getObjectOffset(FrameIdx); +Register Reg = CS.getReg(); +unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( +nullptr, RI.getDwarfRegNum(Reg, true), Offset)); +BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) +.addCFIIndex(CFIIndex) +.setMIFlag(MachineInstr::FrameSetup); + } +}; + +class CFIRestoreRVVRegisterEmitter { + const llvm::RISCVRegisterInfo *TRI; + +public: + CFIRestoreRVVRegisterEmitter(MachineFunction &, const RISCVSubtarget &STI) + : TRI{STI.getRegisterInfo()} {}; lenary wrote: Why is this saved, when the same pointee is passed into `emit` as a reference `RI`? Getting rid of this would simplify the constructor, removing the STI argument. https://github.com/llvm/llvm-project/pull/114227 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [RISCV][NFC] refactor CFI emitting (PR #114227)
@@ -27,6 +27,102 @@ using namespace llvm; +static unsigned getCaleeSavedRVVNumRegs(const Register &BaseReg) { lenary wrote: Typo ```suggestion static unsigned getCalleeSavedRVVNumRegs(const Register &BaseReg) { ``` https://github.com/llvm/llvm-project/pull/114227 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [RISCV][NFC] refactor CFI emitting (PR #114227)
https://github.com/lenary edited https://github.com/llvm/llvm-project/pull/114227 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [RISCV] Support __builtin_cpu_is (PR #116231)
https://github.com/lenary approved this pull request. https://github.com/llvm/llvm-project/pull/116231 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [RISCV] Support __builtin_cpu_is (PR #116231)
@@ -58,6 +58,19 @@ bool hasFastVectorUnalignedAccess(StringRef CPU) { return Info && Info->FastVectorUnalignedAccess; } +bool hasValidCPUModel(StringRef CPU) { + const CPUModel CPUModel = getCPUModel(CPU); + return CPUModel.MVendorID != 0 && CPUModel.MArchID != 0 && lenary wrote: Can you add a test for this error maybe? I think maybe the generic cpus will never have IDs so should be fine for tests. https://github.com/llvm/llvm-project/pull/116231 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [RISCV] Support __builtin_cpu_is (PR #116231)
@@ -22505,6 +22506,57 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, return nullptr; } +Value *CodeGenFunction::EmitRISCVCpuIs(const CallExpr *E) { + const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); + StringRef CPUStr = cast(CPUExpr)->getString(); + return EmitRISCVCpuIs(CPUStr); +} + +Value *CodeGenFunction::EmitRISCVCpuIs(StringRef CPUStr) { + llvm::Type *Int32Ty = Builder.getInt32Ty(); + llvm::Type *Int64Ty = Builder.getInt64Ty(); + llvm::Type *MXLenType = + CGM.getTarget().getTriple().isArch32Bit() ? Int32Ty : Int64Ty; + + llvm::Type *StructTy = llvm::StructType::get(Int32Ty, MXLenType, MXLenType); + llvm::Constant *RISCVCPUModel = + CGM.CreateRuntimeVariable(StructTy, "__riscv_cpu_model"); + cast(RISCVCPUModel)->setDSOLocal(true); + + auto loadRISCVCPUID = [&](unsigned Index, llvm::Type *ValueTy, +CGBuilderTy &Builder, CodeGenModule &CGM) { +llvm::Value *GEPIndices[] = {Builder.getInt32(0), + llvm::ConstantInt::get(Int32Ty, Index)}; +Value *Ptr = Builder.CreateInBoundsGEP(StructTy, RISCVCPUModel, GEPIndices); +Value *CPUID = Builder.CreateAlignedLoad( +ValueTy, Ptr, +CharUnits::fromQuantity(ValueTy->getScalarSizeInBits() / 8)); +return CPUID; + }; + + // Compare mvendorid. + Value *VendorID = loadRISCVCPUID(0, Int32Ty, Builder, CGM); + Value *Result = Builder.CreateICmpEQ( + VendorID, + llvm::ConstantInt::get(Int32Ty, llvm::RISCV::getVendorID(CPUStr))); + + // Compare marchid. + Value *ArchID = loadRISCVCPUID(1, MXLenType, Builder, CGM); + Result = Builder.CreateAnd( + Result, Builder.CreateICmpEQ( + ArchID, llvm::ConstantInt::get( + MXLenType, llvm::RISCV::getArchID(CPUStr; + + // Compare mimplid. + Value *ImplID = loadRISCVCPUID(2, MXLenType, Builder, CGM); + Result = Builder.CreateAnd( + Result, Builder.CreateICmpEQ( + ImplID, llvm::ConstantInt::get( + MXLenType, llvm::RISCV::getImplID(CPUStr; lenary wrote: Currently we are using `getVendorID`, `getArchID` or `getImplID` returning 0 to mean we have no IDs in LLVM for that CPU. On the CPU Core's side, the CSRs will also report 0 if they are not implemented (though I'm not sure what e.g. Linux reports to userspace in this case). When we have no IDs, what comparisons should we be doing? Maybe we should only support `__builtin_cpu_is(...)` for CPUs where we have non-zero values for any of the three items? Otherwise either emit a compile-time error, or return `false` because we don't have a way to actually know if we're on the CPU being asked for? I don't know the right answer here, but I think this implementation isn't handling these cases right. https://github.com/llvm/llvm-project/pull/116231 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [RISCV] Support __builtin_cpu_is (PR #116231)
@@ -1,55 +1,131 @@ -// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm < %s| FileCheck %s +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-X86 +// RUN: %clang_cc1 -triple riscv64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-RV64 +#ifdef __x86_64__ lenary wrote: Two different files is also ok, and the tests can be run in parallel :) https://github.com/llvm/llvm-project/pull/116231 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen] Use cached version of getRegPressureSetLimit (PR #119194)
https://github.com/lenary approved this pull request. LGTM for the target-independent changes. https://github.com/llvm/llvm-project/pull/119194 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen] Use cached version of getRegPressureSetLimit (PR #119194)
@@ -123,6 +123,7 @@ namespace { const TargetRegisterInfo *TRI = nullptr; const MachineFrameInfo *MFI = nullptr; MachineRegisterInfo *MRI = nullptr; +RegisterClassInfo RegClassInfo; lenary wrote: I was thinking this, especially as it has some saved state to work out when it needs to recompute. I think that's probably a good follow-up? https://github.com/llvm/llvm-project/pull/119194 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [Multilib] Custom flags processing for library selection (PR #110659)
https://github.com/lenary edited https://github.com/llvm/llvm-project/pull/110659 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [Multilib] Custom flags processing for library selection (PR #110659)
@@ -92,12 +93,141 @@ MultilibSet &MultilibSet::FilterOut(FilterCallback F) { void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); } -bool MultilibSet::select(const Driver &D, const Multilib::flags_list &Flags, - llvm::SmallVectorImpl &Selected) const { - llvm::StringSet<> FlagSet(expandFlags(Flags)); +static void DiagnoseUnclaimedMultilibCustomFlags( +const Driver &D, const SmallVector &UnclaimedCustomFlagValues, +const SmallVector &CustomFlagDecls) { + struct EditDistanceInfo { +StringRef FlagValue; +unsigned EditDistance; + }; + const unsigned MaxEditDistance = 5; + + for (StringRef Unclaimed : UnclaimedCustomFlagValues) { +std::optional BestCandidate; +for (const auto &Decl : CustomFlagDecls) { + for (const auto &Value : Decl->ValueList) { +const std::string &FlagValueName = Value.Name; +unsigned EditDistance = +Unclaimed.edit_distance(FlagValueName, /*AllowReplacements=*/true, +/*MaxEditDistance=*/MaxEditDistance); +if (!BestCandidate || (EditDistance <= MaxEditDistance && + EditDistance < BestCandidate->EditDistance)) { + BestCandidate = {FlagValueName, EditDistance}; +} + } +} +if (!BestCandidate) + D.Diag(clang::diag::err_drv_unsupported_opt) + << (custom_flag::Prefix + Unclaimed).str(); +else + D.Diag(clang::diag::err_drv_unsupported_opt_with_suggestion) + << (custom_flag::Prefix + Unclaimed).str() + << (custom_flag::Prefix + BestCandidate->FlagValue).str(); + } +} + +namespace clang::driver::custom_flag { +// Map implemented using linear searches as the expected size is too small for +// the overhead of a search tree or a hash table. +class ValueNameToDetailMap { + SmallVector> Mapping; + +public: + template + ValueNameToDetailMap(It FlagDeclsBegin, It FlagDeclsEnd) { +for (auto DeclIt = FlagDeclsBegin; DeclIt != FlagDeclsEnd; ++DeclIt) { + const DeclarationPtr &Decl = *DeclIt; + for (const auto &Value : Decl->ValueList) +Mapping.emplace_back(Value.Name, &Value); +} + } + + const ValueDetail *get(StringRef Key) const { +auto Iter = llvm::find_if( +Mapping, [&](const auto &Pair) { return Pair.first == Key; }); +return Iter != Mapping.end() ? Iter->second : nullptr; + } +}; +} // namespace clang::driver::custom_flag + +std::pair> +MultilibSet::processCustomFlags(const Driver &D, +const Multilib::flags_list &Flags) const { + Multilib::flags_list Result; + SmallVector MacroDefines; + + // Custom flag values detected in the flags list + SmallVector ClaimedCustomFlagValues; + + // Arguments to -fmultilib-flag= that don't correspond to any valid + // custom flag value. An error will be printed out for each of these. + SmallVector UnclaimedCustomFlagValueStrs; + + const auto ValueNameToValueDetail = custom_flag::ValueNameToDetailMap( + CustomFlagDecls.begin(), CustomFlagDecls.end()); + + for (StringRef Flag : Flags) { +if (!Flag.starts_with(custom_flag::Prefix)) { + Result.push_back(Flag.str()); + continue; +} + +StringRef CustomFlagValueStr = Flag.substr(custom_flag::Prefix.size()); +const custom_flag::ValueDetail *Detail = +ValueNameToValueDetail.get(CustomFlagValueStr); +if (Detail) + ClaimedCustomFlagValues.push_back(Detail); +else + UnclaimedCustomFlagValueStrs.push_back(CustomFlagValueStr); + } + + // Set of custom flag declarations for which a value was passed in the flags + // list. This is used to, firstly, detect multiple values for the same flag + // declaration (in this case, the last one wins), and secondly, to detect + // which declarations had no value passed in (in this case, the default value + // is selected). + llvm::SmallSet TriggeredCustomFlagDecls; + + // Detect multiple values for the same flag declaration. Last one wins. + for (auto *CustomFlagValue : llvm::reverse(ClaimedCustomFlagValues)) { +if (!TriggeredCustomFlagDecls.insert(CustomFlagValue->Decl).second) + continue; +Result.push_back(std::string(custom_flag::Prefix) + CustomFlagValue->Name); +if (CustomFlagValue->MacroDefines) + MacroDefines.append(CustomFlagValue->MacroDefines->begin(), + CustomFlagValue->MacroDefines->end()); + } + + // Detect flag declarations with no value passed in. Select default value. + for (const auto &Decl : CustomFlagDecls) { +if (TriggeredCustomFlagDecls.contains(Decl)) + continue; +custom_flag::ValueDetail &CustomFlagValue = +Decl->ValueList[*Decl->DefaultValueIdx]; +Result.push_back(std::string(custom_flag::Prefix) + CustomFlagValue.Name); +if (CustomFlagValue.MacroDefines) + MacroDefines.append(CustomFlagValue.MacroDefines->begin(), + CustomFlagValue.MacroDefines->
[llvm-branch-commits] [clang] [Multilib] Custom flags processing for library selection (PR #110659)
https://github.com/lenary approved this pull request. LGTM, with one tiny nit. https://github.com/llvm/llvm-project/pull/110659 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] Add documentation for Multilib custom flags (PR #114998)
@@ -122,6 +122,76 @@ subclass and a suitable base multilib variant is present then the It is the responsibility of layered multilib authors to ensure that headers and libraries in each layer are complete enough to mask any incompatibilities. +Multilib custom flags += + +Introduction + + +The multilib mechanism supports library variants that correspond to target, +code generation or language command-line flags. Examples include ``--target``, +``-mcpu``, ``-mfpu``, ``-mbranch-protection``, ``-fno-rtti``. However, some library +variants are particular to features that do not correspond to any command-line +option. Multithreading and semihosting, for instance, have no associated +compiler option. + +In order to support the selection of variants for which no compiler option +exists, the multilib specification includes the concept of *custom flags*. +These flags have no impact on code generation and are only used in the multilib +processing. + +Multilib custom flags follow this format in the driver invocation: + +:: + + -fmultilib-flag= + +They are fed into the multilib system alongside the remaining flags. + +Custom flag declarations + + +Custom flags can be declared in the YAML file under the *Flags* section. + +.. code-block:: yaml + + Flags: + - Name: multithreaded +Values: +- Name: no-multithreaded + MacroDefines: [__SINGLE_THREAD__] +- Name: multithreaded +Default: no-multithreaded + +* Name: the name to categorize a flag. +* Values: a list of flag Values (defined below). +* Default: it specifies the name of the value this flag should take if not + specified in the command-line invocation. It must be one value from the Values + field. + +A Default value is useful to save users from specifying custom flags that have a lenary wrote: This makes it sound like setting a default is optional, which it isn't https://github.com/llvm/llvm-project/pull/114998 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [Multilib] Add -fmultilib-flag command-line option (PR #110658)
https://github.com/lenary approved this pull request. https://github.com/llvm/llvm-project/pull/110658 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/19.x: [RISCV] Fix typo in CV_SH_rr_inc pattern (#120246) (PR #120296)
https://github.com/lenary approved this pull request. https://github.com/llvm/llvm-project/pull/120296 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] Add documentation for Multilib custom flags (PR #114998)
https://github.com/lenary approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/114998 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] Add documentation for Multilib custom flags (PR #114998)
lenary wrote: I'm still happy with this, and it is for docs, so I don't think the barrier to landing it is very high. https://github.com/llvm/llvm-project/pull/114998 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/19.x: [RISCV] Don't create BuildPairF64 or SplitF64 nodes without D or Zdinx. (#116159) (PR #121175)
https://github.com/lenary approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/121175 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [Multilib] Custom flags processing for library selection (PR #110659)
@@ -92,12 +93,141 @@ MultilibSet &MultilibSet::FilterOut(FilterCallback F) { void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); } -bool MultilibSet::select(const Driver &D, const Multilib::flags_list &Flags, - llvm::SmallVectorImpl &Selected) const { - llvm::StringSet<> FlagSet(expandFlags(Flags)); +static void DiagnoseUnclaimedMultilibCustomFlags( +const Driver &D, const SmallVector &UnclaimedCustomFlagValues, +const SmallVector &CustomFlagDecls) { + struct EditDistanceInfo { +StringRef FlagValue; +unsigned EditDistance; + }; + const unsigned MaxEditDistance = 5; + + for (StringRef Unclaimed : UnclaimedCustomFlagValues) { +std::optional BestCandidate; +for (const auto &Decl : CustomFlagDecls) { + for (const auto &Value : Decl->ValueList) { +const std::string &FlagValueName = Value.Name; +unsigned EditDistance = +Unclaimed.edit_distance(FlagValueName, /*AllowReplacements=*/true, +/*MaxEditDistance=*/MaxEditDistance); +if (!BestCandidate || (EditDistance <= MaxEditDistance && + EditDistance < BestCandidate->EditDistance)) { + BestCandidate = {FlagValueName, EditDistance}; +} + } +} +if (!BestCandidate) + D.Diag(clang::diag::err_drv_unsupported_opt) + << (custom_flag::Prefix + Unclaimed).str(); +else + D.Diag(clang::diag::err_drv_unsupported_opt_with_suggestion) + << (custom_flag::Prefix + Unclaimed).str() + << (custom_flag::Prefix + BestCandidate->FlagValue).str(); + } +} + +namespace clang::driver::custom_flag { +// Map implemented using linear searches as the expected size is too small for +// the overhead of a search tree or a hash table. +class ValueNameToDetailMap { + SmallVector> Mapping; + +public: + template + ValueNameToDetailMap(It FlagDeclsBegin, It FlagDeclsEnd) { +for (auto DeclIt = FlagDeclsBegin; DeclIt != FlagDeclsEnd; ++DeclIt) { + const DeclarationPtr &Decl = *DeclIt; + for (const auto &Value : Decl->ValueList) +Mapping.emplace_back(Value.Name, &Value); +} + } + + const ValueDetail *get(StringRef Key) const { +auto Iter = llvm::find_if( +Mapping, [&](const auto &Pair) { return Pair.first == Key; }); +return Iter != Mapping.end() ? Iter->second : nullptr; + } +}; +} // namespace clang::driver::custom_flag + +std::pair> +MultilibSet::processCustomFlags(const Driver &D, +const Multilib::flags_list &Flags) const { + Multilib::flags_list Result; + SmallVector MacroDefines; + + // Custom flag values detected in the flags list + SmallVector ClaimedCustomFlagValues; + + // Arguments to -fmultilib-flag= that don't correspond to any valid + // custom flag value. An error will be printed out for each of these. + SmallVector UnclaimedCustomFlagValueStrs; + + const auto ValueNameToValueDetail = custom_flag::ValueNameToDetailMap( + CustomFlagDecls.begin(), CustomFlagDecls.end()); + + for (StringRef Flag : Flags) { +if (!Flag.starts_with(custom_flag::Prefix)) { + Result.push_back(Flag.str()); + continue; +} + +StringRef CustomFlagValueStr = Flag.substr(custom_flag::Prefix.size()); +const custom_flag::ValueDetail *Detail = +ValueNameToValueDetail.get(CustomFlagValueStr); +if (Detail) + ClaimedCustomFlagValues.push_back(Detail); +else + UnclaimedCustomFlagValueStrs.push_back(CustomFlagValueStr); + } + + // Set of custom flag declarations for which a value was passed in the flags + // list. This is used to, firstly, detect multiple values for the same flag + // declaration (in this case, the last one wins), and secondly, to detect + // which declarations had no value passed in (in this case, the default value + // is selected). + llvm::SmallSet TriggeredCustomFlagDecls; + + // Detect multiple values for the same flag declaration. Last one wins. + for (auto *CustomFlagValue : llvm::reverse(ClaimedCustomFlagValues)) { +if (!TriggeredCustomFlagDecls.insert(CustomFlagValue->Decl).second) + continue; +Result.push_back(std::string(custom_flag::Prefix) + CustomFlagValue->Name); +if (CustomFlagValue->MacroDefines) + MacroDefines.append(CustomFlagValue->MacroDefines->begin(), + CustomFlagValue->MacroDefines->end()); + } + + // Detect flag declarations with no value passed in. Select default value. + for (const auto &Decl : CustomFlagDecls) { +if (TriggeredCustomFlagDecls.contains(Decl)) + continue; +custom_flag::ValueDetail &CustomFlagValue = +Decl->ValueList[*Decl->DefaultValueIdx]; +Result.push_back(std::string(custom_flag::Prefix) + CustomFlagValue.Name); +if (CustomFlagValue.MacroDefines) + MacroDefines.append(CustomFlagValue.MacroDefines->begin(), + CustomFlagValue.MacroDefines->
[llvm-branch-commits] [llvm] release/19.x: [RISCV] Don't create BuildPairF64 or SplitF64 nodes without D or Zdinx. (#116159) (PR #121501)
https://github.com/lenary approved this pull request. LGTM I guess this would have been easier had the original test had `nounwind`, but that's life. I don't think we should change it on the branch. https://github.com/llvm/llvm-project/pull/121501 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [RISCV] Replace @plt/@gotpcrel in data directives with %pltpcrel %gotpcrel (PR #132569)
@@ -2233,8 +2235,17 @@ ParseStatus RISCVAsmParser::parseOperandWithSpecifier(OperandVector &Operands) { SMLoc S = getLoc(); SMLoc E; - if (!parseOptionalToken(AsmToken::Percent) || - getLexer().getKind() != AsmToken::Identifier) + if (!parseOptionalToken(AsmToken::Percent)) +return Error(getLoc(), "expected '%' relocation specifier"); + const MCExpr *Expr = nullptr; + bool Failed = parseExprWithSpecifier(Expr, E); + if (!Failed) +Operands.push_back(RISCVOperand::createImm(Expr, S, E, isRV64())); + return Failed; +} + +bool RISCVAsmParser::parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E) { lenary wrote: Would be great to move these all to ParseStatus, but this PR isn't the right moment. https://github.com/llvm/llvm-project/pull/132569 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [RISCV] Replace @plt/@gotpcrel in data directives with %pltpcrel %gotpcrel (PR #132569)
@@ -2233,8 +2235,17 @@ ParseStatus RISCVAsmParser::parseOperandWithSpecifier(OperandVector &Operands) { SMLoc S = getLoc(); SMLoc E; - if (!parseOptionalToken(AsmToken::Percent) || - getLexer().getKind() != AsmToken::Identifier) + if (!parseOptionalToken(AsmToken::Percent)) +return Error(getLoc(), "expected '%' relocation specifier"); lenary wrote: Nit: this means the % is not optional, is there maybe a better way to write this? ```suggestion if (parseToken(AsmToken::Percent, "expected '%' relocation specifier")) return ParseStatus::Failure; ``` maybe? https://github.com/llvm/llvm-project/pull/132569 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [RISCV] Replace @plt/@gotpcrel in data directives with %pltpcrel %gotpcrel (PR #132569)
https://github.com/lenary edited https://github.com/llvm/llvm-project/pull/132569 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [RISCV] Replace @plt/@gotpcrel in data directives with %pltpcrel %gotpcrel (PR #132569)
https://github.com/lenary approved this pull request. I am happy with this, but I don't know if Jessica has more feedback. Comments below are nits or for follow-ups https://github.com/llvm/llvm-project/pull/132569 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [RISCV, test] Replace -riscv-no-aliases with -M no-aliases (PR #134879)
https://github.com/lenary approved this pull request. https://github.com/llvm/llvm-project/pull/134879 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] release/20.x: [RISCV] Allow `Zicsr`/`Zifencei` to duplicate with `g` (#136842) (PR #137490)
https://github.com/lenary approved this pull request. https://github.com/llvm/llvm-project/pull/137490 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] RISCVAsmParser: Reject call foo@invalid (PR #135509)
https://github.com/lenary approved this pull request. https://github.com/llvm/llvm-project/pull/135509 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [RISCV] Replace @plt/@gotpcrel in data directives with %plt %gotpcrel (PR #132569)
@@ -18,6 +18,6 @@ .globl _start _start: .data - .word foo@PLT - . - .word foo@PLT - . + 1 - .word foo@PLT - . - 1 + .word %plt(foo - .) lenary wrote: Yeah I don't like `%plt(foo - .)`, because the thing being put into the instruction is really the difference between foo's PLT entry's address, and the current address (rather than a PLT entry for the difference between foo and the current address). I would much prefer `%pltpcrel(foo)` if `%plt(foo)-.` is not a direction you are happy with, given the existing `%gotpcrel(foo)` means the difference between the current address and foo's GOT entry's address. https://github.com/llvm/llvm-project/pull/132569 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits