Index: llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -37,13 +37,17 @@ namespace { class RISCVAsmPrinter : public AsmPrinter { + const MCSubtargetInfo *STI; + public: explicit RISCVAsmPrinter(TargetMachine &TM, std::unique_ptr Streamer) - : AsmPrinter(TM, std::move(Streamer)) {} + : AsmPrinter(TM, std::move(Streamer)), STI(TM.getMCSubtargetInfo()) {} StringRef getPassName() const override { return "RISCV Assembly Printer"; } + void SetupMachineFunction(MachineFunction &MF) override; + void EmitInstruction(const MachineInstr *MI) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, @@ -66,8 +70,7 @@ #include "RISCVGenCompressInstEmitter.inc" void RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) { MCInst CInst; - bool Res = compressInst(CInst, Inst, *TM.getMCSubtargetInfo(), - OutStreamer->getContext()); + bool Res = compressInst(CInst, Inst, *STI, OutStreamer->getContext()); if (Res) ++RISCVNumInstrsCompressed; AsmPrinter::EmitToStreamer(*OutStreamer, Res ? CInst : Inst); @@ -154,6 +157,17 @@ return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS); } +void RISCVAsmPrinter::SetupMachineFunction(MachineFunction &MF) { + // Set the current MCSubtargetInfo to a copy which has the correct + // feature bits for the current MachineFunction + MCSubtargetInfo &NewSTI = + OutStreamer->getContext().getSubtargetCopy(*TM.getMCSubtargetInfo()); + NewSTI.setFeatureBits(MF.getSubtarget().getFeatureBits()); + STI = &NewSTI; + + return AsmPrinter::SetupMachineFunction(MF); +} + // Force static initialization. extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmPrinter() { RegisterAsmPrinter X(getTheRISCV32Target()); Index: llvm/test/CodeGen/RISCV/compress-float.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/RISCV/compress-float.ll @@ -0,0 +1,48 @@ +; This test is designed to run three times, once with function attributes, once +; with all target attributes added on the command line, and one with compress +; added with the command line and float added via function attributes, all +; three of these should result in the same output. +; +; RUN: cat %s > %t.tgtattr +; RUN: echo 'attributes #0 = { nounwind }' >> %t.tgtattr +; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=+c,+f,+d -filetype=obj \ +; RUN: -disable-block-placement < %t.tgtattr \ +; RUN: | llvm-objdump -d -triple=riscv32 -mattr=+c,+f,+d -M no-aliases - \ +; RUN: | FileCheck -check-prefix=RV32IFDC %s +; +; RUN: cat %s > %t.fnattr +; RUN: echo 'attributes #0 = { nounwind "target-features"="+c,+f,+d" }' >> %t.fnattr +; RUN: llc -mtriple=riscv32 -target-abi ilp32d -filetype=obj \ +; RUN: -disable-block-placement < %t.fnattr \ +; RUN: | llvm-objdump -d -triple=riscv32 -mattr=+c,+f,+d -M no-aliases - \ +; RUN: | FileCheck -check-prefix=RV32IFDC %s +; +; RUN: cat %s > %t.mixedattr +; RUN: echo 'attributes #0 = { nounwind "target-features"="+f,+d" }' >> %t.mixedattr +; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=+c -filetype=obj \ +; RUN: -disable-block-placement < %t.mixedattr \ +; RUN: | llvm-objdump -d -triple=riscv32 -mattr=+c,+f,+d -M no-aliases - \ +; RUN: | FileCheck -check-prefix=RV32IFDC %s + +; This acts as a sanity check for the codegen instruction compression path, +; verifying that the assembled file contains compressed instructions when +; expected. Handling of the compressed ISA is implemented so the same +; transformation patterns should be used whether compressing an input .s file or +; compressing codegen output. This file contains sanity checks using +; instructions which also require one of the floating point extensions. + +define float @float_load(float *%a) nounwind #0 { +; RV32IFDC-LABEL: float_load: +; RV32IFDC: c.flw fa0, 0(a0) +; RV32IFDC-NEXT: c.jr ra + %1 = load volatile float, float* %a + ret float %1 +} + +define double @double_load(double *%a) nounwind #0 { +; RV32IFDC-LABEL: double_load: +; RV32IFDC: c.fld fa0, 0(a0) +; RV32IFDC-NEXT: c.jr ra + %1 = load volatile double, double* %a + ret double %1 +} Index: llvm/test/CodeGen/RISCV/compress.ll =================================================================== --- llvm/test/CodeGen/RISCV/compress.ll +++ llvm/test/CodeGen/RISCV/compress.ll @@ -1,5 +1,17 @@ +; This test is designed to run twice, once with function attributes and once +; with target attributes added on the command line. +; +; RUN: cat %s > %t.tgtattr +; RUN: echo 'attributes #0 = { nounwind }' >> %t.tgtattr ; RUN: llc -mtriple=riscv32 -mattr=+c -filetype=obj \ -; RUN: -disable-block-placement < %s \ +; RUN: -disable-block-placement < %t.tgtattr \ +; RUN: | llvm-objdump -d -triple=riscv32 -mattr=+c -M no-aliases - \ +; RUN: | FileCheck -check-prefix=RV32IC %s +; +; RUN: cat %s > %t.fnattr +; RUN: echo 'attributes #0 = { nounwind "target-features"="+c" }' >> %t.fnattr +; RUN: llc -mtriple=riscv32 -filetype=obj \ +; RUN: -disable-block-placement < %t.fnattr \ ; RUN: | llvm-objdump -d -triple=riscv32 -mattr=+c -M no-aliases - \ ; RUN: | FileCheck -check-prefix=RV32IC %s @@ -17,7 +29,7 @@ ; possible if alternative codegen choices were made, but they belong in a ; different test file. -define i32 @simple_arith(i32 %a, i32 %b) nounwind { +define i32 @simple_arith(i32 %a, i32 %b) nounwind #0 { ; RV32IC-LABEL: simple_arith: ; RV32IC: addi a2, a0, 1 ; RV32IC-NEXT: c.andi a2, 11 @@ -35,7 +47,7 @@ ret i32 %6 } -define i32 @select(i32 %a, i32 *%b) nounwind { +define i32 @select(i32 %a, i32 *%b) nounwind #0 { ; RV32IC-LABEL: select: ; RV32IC: c.lw a2, 0(a1) ; RV32IC-NEXT: c.beqz a2, 4 @@ -111,14 +123,14 @@ ret i32 %val20 } -define i32 @pos_tiny() nounwind { +define i32 @pos_tiny() nounwind #0 { ; RV32IC-LABEL: pos_tiny: ; RV32IC: c.li a0, 18 ; RV32IC-NEXT: c.jr ra ret i32 18 } -define i32 @pos_i32() nounwind { +define i32 @pos_i32() nounwind #0 { ; RV32IC-LABEL: pos_i32: ; RV32IC: lui a0, 423811 ; RV32IC-NEXT: addi a0, a0, -1297 @@ -126,7 +138,7 @@ ret i32 1735928559 } -define i32 @pos_i32_half_compressible() nounwind { +define i32 @pos_i32_half_compressible() nounwind #0 { ; RV32IC-LABEL: pos_i32_half_compressible: ; RV32IC: lui a0, 423810 ; RV32IC-NEXT: c.addi a0, 28 @@ -134,15 +146,14 @@ ret i32 1735925788 } - -define i32 @neg_tiny() nounwind { +define i32 @neg_tiny() nounwind #0 { ; RV32IC-LABEL: neg_tiny: ; RV32IC: c.li a0, -19 ; RV32IC-NEXT: c.jr ra ret i32 -19 } -define i32 @neg_i32() nounwind { +define i32 @neg_i32() nounwind #0 { ; RV32IC-LABEL: neg_i32: ; RV32IC: lui a0, 912092 ; RV32IC-NEXT: addi a0, a0, -273 @@ -150,14 +161,14 @@ ret i32 -559038737 } -define i32 @pos_i32_hi20_only() nounwind { +define i32 @pos_i32_hi20_only() nounwind #0 { ; RV32IC-LABEL: pos_i32_hi20_only: ; RV32IC: c.lui a0, 16 ; RV32IC-NEXT: c.jr ra ret i32 65536 } -define i32 @neg_i32_hi20_only() nounwind { +define i32 @neg_i32_hi20_only() nounwind #0 { ; RV32IC-LABEL: neg_i32_hi20_only: ; RV32IC: c.lui a0, 1048560 ; RV32IC-NEXT: c.jr ra