Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -1661,7 +1661,8 @@ const llvm::Triple::ArchType DebugEntryValueArchs[] = { llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::aarch64, llvm::Triple::arm, llvm::Triple::armeb, llvm::Triple::mips, - llvm::Triple::mipsel, llvm::Triple::mips64, llvm::Triple::mips64el}; + llvm::Triple::mipsel, llvm::Triple::mips64, llvm::Triple::mips64el, + llvm::Triple::riscv32, llvm::Triple::riscv64}; if (Opts.OptimizationLevel > 0 && Opts.hasReducedDebugInfo() && llvm::is_contained(DebugEntryValueArchs, T.getArch())) Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -8985,6 +8985,9 @@ MachineFunction &MF = DAG.getMachineFunction(); + // Call site info for function parameters tracking. + MachineFunction::CallSiteInfo CSInfo; + // Analyze the operands of the call, assigning locations to each operand. SmallVector ArgLocs; CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); @@ -9035,6 +9038,8 @@ if (!IsTailCall) Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL); + const TargetOptions &Options = DAG.getTarget().Options; + // Copy argument values to their designated locations. SmallVector, 8> RegsToPass; SmallVector MemOpChains; @@ -9134,6 +9139,10 @@ if (VA.isRegLoc()) { // Queue up the argument copies and emit them at the end. RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue)); + + if (Options.SupportsDebugEntryValues) + CSInfo.emplace_back(VA.getLocReg(), i); + continue; } else { assert(VA.isMemLoc() && "Argument not register or memory"); assert(!IsTailCall && "Tail call not allowed if stack is used " @@ -9222,13 +9231,17 @@ if (IsTailCall) { MF.getFrameInfo().setHasTailCall(); - return DAG.getNode(RISCVISD::TAIL, DL, NodeTys, Ops); + SDValue Ret = DAG.getNode(RISCVISD::TAIL, DL, NodeTys, Ops); + DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo)); + return Ret; } Chain = DAG.getNode(RISCVISD::CALL, DL, NodeTys, Ops); DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge); Glue = Chain.getValue(1); + DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo)); + // Mark the end of the call, which is glued to the call itself. Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, DL, PtrVT, true), Index: llvm/lib/Target/RISCV/RISCVInstrInfo.h =================================================================== --- llvm/lib/Target/RISCV/RISCVInstrInfo.h +++ llvm/lib/Target/RISCV/RISCVInstrInfo.h @@ -177,6 +177,12 @@ Optional> isRVVSpillForZvlsseg(unsigned Opcode) const; + Optional isAddImmediate(const MachineInstr &MI, + Register Reg) const override; + + Optional describeLoadedValue(const MachineInstr &MI, + Register Reg) const override; + protected: const RISCVSubtarget &STI; }; Index: llvm/lib/Target/RISCV/RISCVInstrInfo.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -25,6 +25,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/MC/MCInstBuilder.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/ErrorHandling.h" @@ -1899,3 +1900,176 @@ return std::make_pair(8u, 1u); } } + +Optional +RISCVInstrInfo::describeLoadedValue(const MachineInstr &MI, + Register Reg) const { + DIExpression *Expr = + DIExpression::get(MI.getMF()->getFunction().getContext(), {}); + + // TODO: Special RISCV instructions that need to be described separately. + if (auto RegImm = isAddImmediate(MI, Reg)) { + Register SrcReg = RegImm->Reg; + int64_t Offset = RegImm->Imm; + + // When SrcReg is $x0, treat loaded value as immediate only, $x0 is a zero + // register. Ex. $x10 = ADDI $x0, 10 + if (SrcReg == RISCV::X0) + return ParamLoadedValue(MachineOperand::CreateImm(Offset), Expr); + + Expr = DIExpression::prepend(Expr, DIExpression::ApplyOffset, Offset); + return ParamLoadedValue(MachineOperand::CreateReg(SrcReg, false), Expr); + } else if (auto DestSrc = isCopyInstr(MI)) { + const MachineFunction *MF = MI.getMF(); + const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); + Register DestReg = DestSrc->Destination->getReg(); + // TODO: Handle cases where the Reg is sub- or super-register of the + // DestReg. + if (TRI->isSuperRegister(Reg, DestReg) || TRI->isSubRegister(Reg, DestReg)) + return None; + } + + return TargetInstrInfo::describeLoadedValue(MI, Reg); +} + +Optional RISCVInstrInfo::isAddImmediate(const MachineInstr &MI, + Register Reg) const { + const MachineOperand &Op0 = MI.getOperand(0); + if (!Op0.isReg() || Reg != Op0.getReg()) + return None; + + switch (MI.getOpcode()) { + case RISCV::ADDI: { + const MachineOperand &Dop = MI.getOperand(0); + const MachineOperand &Sop1 = MI.getOperand(1); + const MachineOperand &Sop2 = MI.getOperand(2); + if (Dop.isReg() && Sop1.isReg() && Sop2.isImm()) + return RegImmPair{Sop1.getReg(), Sop2.getImm()}; + break; + } + case RISCV::LUI: { + const MachineOperand &Dop = MI.getOperand(0); + const MachineOperand &Sop1 = MI.getOperand(1); + if (Dop.isReg() && Sop1.isImm()) + return RegImmPair{RISCV::X0, Sop1.getImm() << 12}; + break; + } + case RISCV::ANDI: { + const MachineOperand &Dop = MI.getOperand(0); + const MachineOperand &Sop1 = MI.getOperand(1); + const MachineOperand &Sop2 = MI.getOperand(2); + if (Dop.isReg() && Sop1.isReg() && Sop2.isImm()) + if (Sop1.getReg() == RISCV::X0 || Sop2.getImm() == (uint64_t)0) + return RegImmPair{RISCV::X0, (uint64_t)0}; + break; + } + case RISCV::ORI: + case RISCV::XORI: { + const MachineOperand &Dop = MI.getOperand(0); + const MachineOperand &Sop1 = MI.getOperand(1); + const MachineOperand &Sop2 = MI.getOperand(2); + if (Dop.isReg() && Sop1.isReg() && Sop2.isImm()) { + if (Sop1.getReg() == RISCV::X0) + return RegImmPair{RISCV::X0, Sop2.getImm()}; + if (Sop2.getImm() == (uint64_t)0) + return RegImmPair{Sop1.getReg(), Sop2.getImm()}; + } + break; + } + case RISCV::SLLI: + case RISCV::SRLI: + case RISCV::SRAI: { + const MachineOperand &Dop = MI.getOperand(0); + const MachineOperand &Sop1 = MI.getOperand(1); + const MachineOperand &Sop2 = MI.getOperand(2); + if (Dop.isReg() && Sop1.isReg() && Sop2.isImm()) { + if (Sop1.getReg() == RISCV::X0) + return RegImmPair{RISCV::X0, (uint64_t)0}; + if (Sop2.getImm() == (uint64_t)0) + return RegImmPair{Sop1.getReg(), Sop2.getImm()}; + } + break; + } + case RISCV::AND: { + const MachineOperand &Dop = MI.getOperand(0); + const MachineOperand &Sop1 = MI.getOperand(1); + const MachineOperand &Sop2 = MI.getOperand(2); + if (Dop.isReg() && Sop1.isReg() && Sop2.isReg()) { + if (Sop1.getReg() == Sop2.getReg()) + return RegImmPair{Sop1.getReg(), (uint64_t)0}; + if (Sop1.getReg() == RISCV::X0 || Sop2.getReg() == RISCV::X0) + return RegImmPair{RISCV::X0, (uint64_t)0}; + } + break; + } + case RISCV::OR: { + const MachineOperand &Dop = MI.getOperand(0); + const MachineOperand &Sop1 = MI.getOperand(1); + const MachineOperand &Sop2 = MI.getOperand(2); + if (Dop.isReg() && Sop1.isReg() && Sop2.isReg()) { + if (Sop1.getReg() == Sop2.getReg()) + return RegImmPair{Sop1.getReg(), (uint64_t)0}; + if (Sop1.getReg() == RISCV::X0) + return RegImmPair{Sop2.getReg(), (uint64_t)0}; + if (Sop2.getReg() == RISCV::X0) + return RegImmPair{Sop1.getReg(), (uint64_t)0}; + } + break; + } + case RISCV::XOR: { + const MachineOperand &Dop = MI.getOperand(0); + const MachineOperand &Sop1 = MI.getOperand(1); + const MachineOperand &Sop2 = MI.getOperand(2); + if (Dop.isReg() && Sop1.isReg() && Sop2.isReg()) { + if (Sop1.getReg() == Sop2.getReg()) + return RegImmPair{RISCV::X0, (uint64_t)0}; + if (Sop1.getReg() == RISCV::X0) + return RegImmPair{Sop2.getReg(), (uint64_t)0}; + if (Sop2.getReg() == RISCV::X0) + return RegImmPair{Sop1.getReg(), (uint64_t)0}; + } + break; + } + case RISCV::ADD: { + const MachineOperand &Dop = MI.getOperand(0); + const MachineOperand &Sop1 = MI.getOperand(1); + const MachineOperand &Sop2 = MI.getOperand(2); + if (Dop.isReg() && Sop1.isReg() && Sop2.isReg()) { + if (Sop1.getReg() == RISCV::X0 && Sop2.getReg() == RISCV::X0) + return RegImmPair{RISCV::X0, (uint64_t)0}; + if (Sop1.getReg() == RISCV::X0) + return RegImmPair{Sop2.getReg(), (uint64_t)0}; + if (Sop2.getReg() == RISCV::X0) + return RegImmPair{Sop1.getReg(), (uint64_t)0}; + } + break; + } + case RISCV::SUB: { + const MachineOperand &Dop = MI.getOperand(0); + const MachineOperand &Sop1 = MI.getOperand(1); + const MachineOperand &Sop2 = MI.getOperand(2); + if (Dop.isReg() && Sop1.isReg() && Sop2.isReg()) { + if (Sop1.getReg() == Sop2.getReg()) + return RegImmPair{RISCV::X0, (uint64_t)0}; + if (Sop2.getReg() == RISCV::X0) + return RegImmPair{Sop1.getReg(), (uint64_t)0}; + } + break; + } + case RISCV::SLL: + case RISCV::SRL: + case RISCV::SRA: { + const MachineOperand &Dop = MI.getOperand(0); + const MachineOperand &Sop1 = MI.getOperand(1); + const MachineOperand &Sop2 = MI.getOperand(2); + if (Dop.isReg() && Sop1.isReg() && Sop2.isReg()) { + if (Sop1.getReg() == RISCV::X0) + return RegImmPair{RISCV::X0, (uint64_t)0}; + if (Sop2.getReg() == RISCV::X0) + return RegImmPair{Sop1.getReg(), (uint64_t)0}; + } + break; + } + } + return None; +} Index: llvm/lib/Target/RISCV/RISCVTargetMachine.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -71,6 +71,9 @@ // RISC-V supports the MachineOutliner. setMachineOutliner(true); + + // RISC-V supports the debug entry values. + setSupportsDebugEntryValues(true); } const RISCVSubtarget * Index: llvm/test/CodeGen/RISCV/call-site-info-output.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/RISCV/call-site-info-output.ll @@ -0,0 +1,215 @@ +;; Test riscv32: +; RUN: llc -mtriple=riscv32 -emit-call-site-info -stop-before=finalize-isel %s -o - | \ +; RUN: llc -mtriple=riscv32 -emit-call-site-info -x='mir' -run-pass=finalize-isel -o -| FileCheck %s + +;; Test riscv64: +; RUN: llc -mtriple=riscv64 -emit-call-site-info -stop-before=finalize-isel %s -o - | \ +; RUN: llc -mtriple=riscv64 -emit-call-site-info -x='mir' -run-pass=finalize-isel -o -| FileCheck %s --check-prefix=CHECK64 + + + +;; Source: +;; extern void addi_instr (long int, long int, long int); +;; extern void add_instr (long int, long int, long int); +;; extern void andi_instr (long int, long int, long int); +;; extern void and_instr (long int, long int, long int); +;; extern void lui_instr (long int, long int, long int); +;; extern void or_instr (long int, long int, long int); +;; extern void ori_xori_instr (long int, long int, long int); +;; extern void slli_srli_srai_instr (long int, long int, long int); +;; extern void sll_srl_sra_instr (long int, long int, long int); +;; extern void sub_instr (long int, long int, long int); +;; extern void xor_instr (long int, long int, long int); +;; long int fn2 (long int a, long int b, long int c) +;; { +;; long int q = 2 * a; +;; addi_instr (1,2,3); +;; add_instr (4,5,6); +;; andi_instr (7,8,9); +;; and_instr (10,11,12); +;; lui_instr (13,14,15); +;; or_instr (16,17,18); +;; ori_xori_instr (19,20,21); +;; slli_srli_srai_instr (22,23,24); +;; sll_srl_sra_instr (25,26,27); +;; sub_instr (28,29,30); +;; xor_instr (31,32,33); +;; return 0; +;; } + +;; Test riscv32: +; CHECK: name: fn2 +; CHECK: callSites: +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$x10' +; CHECK-NEXT: arg: 1, reg: '$x11' +; CHECK-NEXT: arg: 2, reg: '$x12' +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$x10' +; CHECK-NEXT: arg: 1, reg: '$x11' +; CHECK-NEXT: arg: 2, reg: '$x12' +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$x10' +; CHECK-NEXT: arg: 1, reg: '$x11' +; CHECK-NEXT: arg: 2, reg: '$x12' +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$x10' +; CHECK-NEXT: arg: 1, reg: '$x11' +; CHECK-NEXT: arg: 2, reg: '$x12' +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$x10' +; CHECK-NEXT: arg: 1, reg: '$x11' +; CHECK-NEXT: arg: 2, reg: '$x12' +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$x10' +; CHECK-NEXT: arg: 1, reg: '$x11' +; CHECK-NEXT: arg: 2, reg: '$x12' +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$x10' +; CHECK-NEXT: arg: 1, reg: '$x11' +; CHECK-NEXT: arg: 2, reg: '$x12' +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$x10' +; CHECK-NEXT: arg: 1, reg: '$x11' +; CHECK-NEXT: arg: 2, reg: '$x12' +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$x10' +; CHECK-NEXT: arg: 1, reg: '$x11' +; CHECK-NEXT: arg: 2, reg: '$x12' +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$x10' +; CHECK-NEXT: arg: 1, reg: '$x11' +; CHECK-NEXT: arg: 2, reg: '$x12' +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$x10' +; CHECK-NEXT: arg: 1, reg: '$x11' +; CHECK-NEXT: arg: 2, reg: '$x12' + +;; Test riscv64: +; CHECK64: name: fn2 +; CHECK64: callSites: +; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK64-NEXT: arg: 0, reg: '$x10' +; CHECK64-NEXT: arg: 1, reg: '$x11' +; CHECK64-NEXT: arg: 2, reg: '$x12' +; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK64-NEXT: arg: 0, reg: '$x10' +; CHECK64-NEXT: arg: 1, reg: '$x11' +; CHECK64-NEXT: arg: 2, reg: '$x12' +; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK64-NEXT: arg: 0, reg: '$x10' +; CHECK64-NEXT: arg: 1, reg: '$x11' +; CHECK64-NEXT: arg: 2, reg: '$x12' +; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK64-NEXT: arg: 0, reg: '$x10' +; CHECK64-NEXT: arg: 1, reg: '$x11' +; CHECK64-NEXT: arg: 2, reg: '$x12' +; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK64-NEXT: arg: 0, reg: '$x10' +; CHECK64-NEXT: arg: 1, reg: '$x11' +; CHECK64-NEXT: arg: 2, reg: '$x12' +; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK64-NEXT: arg: 0, reg: '$x10' +; CHECK64-NEXT: arg: 1, reg: '$x11' +; CHECK64-NEXT: arg: 2, reg: '$x12' +; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK64-NEXT: arg: 0, reg: '$x10' +; CHECK64-NEXT: arg: 1, reg: '$x11' +; CHECK64-NEXT: arg: 2, reg: '$x12' +; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK64-NEXT: arg: 0, reg: '$x10' +; CHECK64-NEXT: arg: 1, reg: '$x11' +; CHECK64-NEXT: arg: 2, reg: '$x12' +; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK64-NEXT: arg: 0, reg: '$x10' +; CHECK64-NEXT: arg: 1, reg: '$x11' +; CHECK64-NEXT: arg: 2, reg: '$x12' +; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK64-NEXT: arg: 0, reg: '$x10' +; CHECK64-NEXT: arg: 1, reg: '$x11' +; CHECK64-NEXT: arg: 2, reg: '$x12' +; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK64-NEXT: arg: 0, reg: '$x10' +; CHECK64-NEXT: arg: 1, reg: '$x11' +; CHECK64-NEXT: arg: 2, reg: '$x12' + + +; Function Attrs: nounwind +define dso_local i32 @fn2(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 !dbg !8 { +entry: + call void @llvm.dbg.value(metadata i32 %a, metadata !13, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.value(metadata i32 %b, metadata !14, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.value(metadata i32 %c, metadata !15, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.value(metadata !DIArgList(i32 2, i32 %a), metadata !16, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_mul, DW_OP_stack_value)), !dbg !17 + tail call void @addi_instr(i32 1, i32 2, i32 3) #3, !dbg !17 + tail call void @add_instr(i32 4, i32 5, i32 6) #3, !dbg !17 + tail call void @andi_instr(i32 7, i32 8, i32 9) #3, !dbg !17 + tail call void @and_instr(i32 10, i32 11, i32 12) #3, !dbg !17 + tail call void @lui_instr(i32 13, i32 14, i32 15) #3, !dbg !17 + tail call void @or_instr(i32 16, i32 17, i32 18) #3, !dbg !17 + tail call void @ori_xori_instr(i32 19, i32 20, i32 21) #3, !dbg !17 + tail call void @slli_srli_srai_instr(i32 22, i32 23, i32 24) #3, !dbg !17 + tail call void @sll_srl_sra_instr(i32 25, i32 26, i32 27) #3, !dbg !17 + tail call void @sub_instr(i32 28, i32 29, i32 30) #3, !dbg !17 + tail call void @xor_instr(i32 31, i32 32, i32 33) #3, !dbg !17 + ret i32 0, !dbg !17 +} + +declare !dbg !30 dso_local void @addi_instr(i32, i32, i32) local_unnamed_addr #1 + +declare !dbg !34 dso_local void @add_instr(i32, i32, i32) local_unnamed_addr #1 + +declare !dbg !35 dso_local void @andi_instr(i32, i32, i32) local_unnamed_addr #1 + +declare !dbg !36 dso_local void @and_instr(i32, i32, i32) local_unnamed_addr #1 + +declare !dbg !37 dso_local void @lui_instr(i32, i32, i32) local_unnamed_addr #1 + +declare !dbg !38 dso_local void @or_instr(i32, i32, i32) local_unnamed_addr #1 + +declare !dbg !39 dso_local void @ori_xori_instr(i32, i32, i32) local_unnamed_addr #1 + +declare !dbg !40 dso_local void @slli_srli_srai_instr(i32, i32, i32) local_unnamed_addr #1 + +declare !dbg !41 dso_local void @sll_srl_sra_instr(i32, i32, i32) local_unnamed_addr #1 + +declare !dbg !42 dso_local void @sub_instr(i32, i32, i32) local_unnamed_addr #1 + +declare !dbg !43 dso_local void @xor_instr(i32, i32, i32) local_unnamed_addr #1 + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/") +!2 = !{i32 7, !"Dwarf Version", i32 4} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 1, !"target-abi", !"ilp32d"} +!6 = !{i32 1, !"SmallDataLimit", i32 8} +!7 = !{!"clang version 14.0.0"} +!8 = distinct !DISubprogram(name: "fn2", scope: !1, file: !1, line: 14, type: !9, scopeLine: 15, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12) +!9 = !DISubroutineType(types: !10) +!10 = !{!11, !11, !11, !11} +!11 = !DIBasicType(name: "long", size: 32, encoding: DW_ATE_signed) +!12 = !{!13, !14, !15, !16} +!13 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 14, type: !11) +!14 = !DILocalVariable(name: "b", arg: 2, scope: !8, file: !1, line: 14, type: !11) +!15 = !DILocalVariable(name: "c", arg: 3, scope: !8, file: !1, line: 14, type: !11) +!16 = !DILocalVariable(name: "q", scope: !8, file: !1, line: 16, type: !11) +!17 = !DILocation(line: 0, scope: !8) +!30 = !DISubprogram(name: "addi_instr", scope: !1, file: !1, line: 1, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) +!31 = !DISubroutineType(types: !32) +!32 = !{null, !11, !11, !11} +!33 = !{} +!34 = !DISubprogram(name: "add_instr", scope: !1, file: !1, line: 2, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) +!35 = !DISubprogram(name: "andi_instr", scope: !1, file: !1, line: 3, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) +!36 = !DISubprogram(name: "and_instr", scope: !1, file: !1, line: 4, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) +!37 = !DISubprogram(name: "lui_instr", scope: !1, file: !1, line: 5, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) +!38 = !DISubprogram(name: "or_instr", scope: !1, file: !1, line: 6, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) +!39 = !DISubprogram(name: "ori_xori_instr", scope: !1, file: !1, line: 7, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) +!40 = !DISubprogram(name: "slli_srli_srai_instr", scope: !1, file: !1, line: 8, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) +!41 = !DISubprogram(name: "sll_srl_sra_instr", scope: !1, file: !1, line: 9, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) +!42 = !DISubprogram(name: "sub_instr", scope: !1, file: !1, line: 10, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) +!43 = !DISubprogram(name: "xor_instr", scope: !1, file: !1, line: 11, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) Index: llvm/test/DebugInfo/MIR/RISCV/dbg-call-site-param.mir =================================================================== --- /dev/null +++ llvm/test/DebugInfo/MIR/RISCV/dbg-call-site-param.mir @@ -0,0 +1,633 @@ +## Test riscv32: +# RUN: llc -mtriple=riscv32 -emit-call-site-info -start-after=machineverifier -filetype=obj %s -o -| llvm-dwarfdump -| FileCheck %s + +## Test riscv64: +# RUN: llc -mtriple=riscv64 -emit-call-site-info -start-after=machineverifier -filetype=obj %s -o -| llvm-dwarfdump -| FileCheck %s --check-prefix=CHECK64 + +## Following code is used for producing this test case. +## Hardcoding for MIR level testing (for instructions other than ADDI instructions) +## +## extern void addi_instr (long int, long int, long int); +## extern void add_instr (long int, long int, long int); +## extern void andi_instr (long int, long int, long int); +## extern void and_instr (long int, long int, long int); +## extern void lui_instr (long int, long int, long int); +## extern void or_instr (long int, long int, long int); +## extern void ori_xori_instr (long int, long int, long int); +## extern void slli_srli_srai_instr (long int, long int, long int); +## extern void sll_srl_sra_instr (long int, long int, long int); +## extern void sub_instr (long int, long int, long int); +## extern void xor_instr (long int, long int, long int); +## long int fn2 (long int a, long int b, long int c) +## { +## long int q = 2 * a; +## addi_instr (1,2,3); +## add_instr (4,5,6); +## andi_instr (7,8,9); +## and_instr (10,11,12); +## lui_instr (13,14,15); +## or_instr (16,17,18); +## ori_xori_instr (19,20,21); +## slli_srli_srai_instr (22,23,24); +## sll_srl_sra_instr (25,26,27); +## sub_instr (28,29,30); +## xor_instr (31,32,33); +## return 0; +## } + + +## Test riscv32: + +# CHECK: DW_TAG_GNU_call_site +# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "addi_instr") +# CHECK-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit3) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit2) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit1) + +# CHECK: DW_TAG_GNU_call_site +# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "add_instr") +# CHECK-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + +# CHECK: DW_TAG_GNU_call_site +# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "andi_instr") +# CHECK-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) + +# CHECK: DW_TAG_GNU_call_site +# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "and_instr") +# CHECK-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) + +# CHECK: DW_TAG_GNU_call_site +# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "lui_instr") +# CHECK-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_constu 0x7000) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_constu 0x6000) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_constu 0x5000) + +# CHECK: DW_TAG_GNU_call_site +# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "or_instr") +# CHECK-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + +# CHECK: DW_TAG_GNU_call_site +# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "ori_xori_instr") +# CHECK-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit7) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit5) + +# CHECK: DW_TAG_GNU_call_site +# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "slli_srli_srai_instr") +# CHECK-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + +# CHECK: DW_TAG_GNU_call_site +# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "sll_srl_sra_instr") +# CHECK-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + +# CHECK: DW_TAG_GNU_call_site +# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "sub_instr") +# CHECK-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + +# CHECK: DW_TAG_GNU_call_site +# CHECK-NEXT: DW_AT_abstract_origin ({{.*}} "xor_instr") +# CHECK-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK-EMPTY: +# CHECK-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + + +## Test riscv64: + +# CHECK64: DW_TAG_GNU_call_site +# CHECK64-NEXT: DW_AT_abstract_origin ({{.*}} "addi_instr") +# CHECK64-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit3) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit2) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit1) + +# CHECK64: DW_TAG_GNU_call_site +# CHECK64-NEXT: DW_AT_abstract_origin ({{.*}} "add_instr") +# CHECK64-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + +# CHECK64: DW_TAG_GNU_call_site +# CHECK64-NEXT: DW_AT_abstract_origin ({{.*}} "andi_instr") +# CHECK64-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) + +# CHECK64: DW_TAG_GNU_call_site +# CHECK64-NEXT: DW_AT_abstract_origin ({{.*}} "and_instr") +# CHECK64-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) + +# CHECK64: DW_TAG_GNU_call_site +# CHECK64-NEXT: DW_AT_abstract_origin ({{.*}} "lui_instr") +# CHECK64-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_constu 0x7000) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_constu 0x6000) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_constu 0x5000) + +# CHECK64: DW_TAG_GNU_call_site +# CHECK64-NEXT: DW_AT_abstract_origin ({{.*}} "or_instr") +# CHECK64-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + +# CHECK64: DW_TAG_GNU_call_site +# CHECK64-NEXT: DW_AT_abstract_origin ({{.*}} "ori_xori_instr") +# CHECK64-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit7) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit5) + +# CHECK64: DW_TAG_GNU_call_site +# CHECK64-NEXT: DW_AT_abstract_origin ({{.*}} "slli_srli_srai_instr") +# CHECK64-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + +# CHECK64: DW_TAG_GNU_call_site +# CHECK64-NEXT: DW_AT_abstract_origin ({{.*}} "sll_srl_sra_instr") +# CHECK64-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + +# CHECK64: DW_TAG_GNU_call_site +# CHECK64-NEXT: DW_AT_abstract_origin ({{.*}} "sub_instr") +# CHECK64-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + +# CHECK64: DW_TAG_GNU_call_site +# CHECK64-NEXT: DW_AT_abstract_origin ({{.*}} "xor_instr") +# CHECK64-NEXT: DW_AT_low_pc ({{.*}}) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg12 X12) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg11 X11) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit0) +# CHECK64-EMPTY: +# CHECK64-NEXT: DW_TAG_GNU_call_site_parameter +# CHECK64-NEXT: DW_AT_location (DW_OP_reg10 X10) +# CHECK64-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +0) + +--- | + + ; Function Attrs: nounwind + define dso_local i32 @fn2(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 !dbg !8 { + entry: + call void @llvm.dbg.value(metadata i32 %a, metadata !13, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.value(metadata i32 %b, metadata !14, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.value(metadata i32 %c, metadata !15, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.value(metadata !DIArgList(i32 2, i32 %a), metadata !16, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_mul, DW_OP_stack_value)), !dbg !17 + tail call void @addi_instr(i32 1, i32 2, i32 3) #3, !dbg !17 + tail call void @add_instr(i32 4, i32 5, i32 6) #3, !dbg !17 + tail call void @andi_instr(i32 7, i32 8, i32 9) #3, !dbg !17 + tail call void @and_instr(i32 10, i32 11, i32 12) #3, !dbg !17 + tail call void @lui_instr(i32 13, i32 14, i32 15) #3, !dbg !17 + tail call void @or_instr(i32 16, i32 17, i32 18) #3, !dbg !17 + tail call void @ori_xori_instr(i32 19, i32 20, i32 21) #3, !dbg !17 + tail call void @slli_srli_srai_instr(i32 22, i32 23, i32 24) #3, !dbg !17 + tail call void @sll_srl_sra_instr(i32 25, i32 26, i32 27) #3, !dbg !17 + tail call void @sub_instr(i32 28, i32 29, i32 30) #3, !dbg !17 + tail call void @xor_instr(i32 31, i32 32, i32 33) #3, !dbg !17 + ret i32 0, !dbg !17 + } + + declare !dbg !30 dso_local void @addi_instr(i32, i32, i32) local_unnamed_addr #1 + + declare !dbg !34 dso_local void @add_instr(i32, i32, i32) local_unnamed_addr #1 + + declare !dbg !35 dso_local void @andi_instr(i32, i32, i32) local_unnamed_addr #1 + + declare !dbg !36 dso_local void @and_instr(i32, i32, i32) local_unnamed_addr #1 + + declare !dbg !37 dso_local void @lui_instr(i32, i32, i32) local_unnamed_addr #1 + + declare !dbg !38 dso_local void @or_instr(i32, i32, i32) local_unnamed_addr #1 + + declare !dbg !39 dso_local void @ori_xori_instr(i32, i32, i32) local_unnamed_addr #1 + + declare !dbg !40 dso_local void @slli_srli_srai_instr(i32, i32, i32) local_unnamed_addr #1 + + declare !dbg !41 dso_local void @sll_srl_sra_instr(i32, i32, i32) local_unnamed_addr #1 + + declare !dbg !42 dso_local void @sub_instr(i32, i32, i32) local_unnamed_addr #1 + + declare !dbg !43 dso_local void @xor_instr(i32, i32, i32) local_unnamed_addr #1 + + ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn + declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!2, !3, !4, !5, !6} + !llvm.ident = !{!7} + + !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) + !1 = !DIFile(filename: "test.c", directory: "/") + !2 = !{i32 7, !"Dwarf Version", i32 4} + !3 = !{i32 2, !"Debug Info Version", i32 3} + !4 = !{i32 1, !"wchar_size", i32 4} + !5 = !{i32 1, !"target-abi", !"ilp32d"} + !6 = !{i32 1, !"SmallDataLimit", i32 8} + !7 = !{!"clang version 14.0.0"} + !8 = distinct !DISubprogram(name: "fn2", scope: !1, file: !1, line: 14, type: !9, scopeLine: 15, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12) + !9 = !DISubroutineType(types: !10) + !10 = !{!11, !11, !11, !11} + !11 = !DIBasicType(name: "long", size: 32, encoding: DW_ATE_signed) + !12 = !{!13, !14, !15, !16} + !13 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 14, type: !11) + !14 = !DILocalVariable(name: "b", arg: 2, scope: !8, file: !1, line: 14, type: !11) + !15 = !DILocalVariable(name: "c", arg: 3, scope: !8, file: !1, line: 14, type: !11) + !16 = !DILocalVariable(name: "q", scope: !8, file: !1, line: 16, type: !11) + !17 = !DILocation(line: 0, scope: !8) + !30 = !DISubprogram(name: "addi_instr", scope: !1, file: !1, line: 1, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) + !31 = !DISubroutineType(types: !32) + !32 = !{null, !11, !11, !11} + !33 = !{} + !34 = !DISubprogram(name: "add_instr", scope: !1, file: !1, line: 2, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) + !35 = !DISubprogram(name: "andi_instr", scope: !1, file: !1, line: 3, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) + !36 = !DISubprogram(name: "and_instr", scope: !1, file: !1, line: 4, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) + !37 = !DISubprogram(name: "lui_instr", scope: !1, file: !1, line: 5, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) + !38 = !DISubprogram(name: "or_instr", scope: !1, file: !1, line: 6, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) + !39 = !DISubprogram(name: "ori_xori_instr", scope: !1, file: !1, line: 7, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) + !40 = !DISubprogram(name: "slli_srli_srai_instr", scope: !1, file: !1, line: 8, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) + !41 = !DISubprogram(name: "sll_srl_sra_instr", scope: !1, file: !1, line: 9, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) + !42 = !DISubprogram(name: "sub_instr", scope: !1, file: !1, line: 10, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) + !43 = !DISubprogram(name: "xor_instr", scope: !1, file: !1, line: 11, type: !31, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !33) + +... +--- +name: fn2 +alignment: 2 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +failsVerification: false +tracksDebugUserValues: true +registers: [] +liveins: [] +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 16 + offsetAdjustment: 0 + maxAlignment: 4 + adjustsStack: true + hasCalls: true + stackProtector: '' + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + hasTailCall: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: + - { id: 0, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4, + stack-id: default, callee-saved-register: '$x1', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } +callSites: + - { bb: 0, offset: 14, fwdArgRegs: + - { arg: 0, reg: '$x10' } + - { arg: 1, reg: '$x11' } + - { arg: 2, reg: '$x12' } } + - { bb: 0, offset: 18, fwdArgRegs: + - { arg: 0, reg: '$x10' } + - { arg: 1, reg: '$x11' } + - { arg: 2, reg: '$x12' } } + - { bb: 0, offset: 22, fwdArgRegs: + - { arg: 0, reg: '$x10' } + - { arg: 1, reg: '$x11' } + - { arg: 2, reg: '$x12' } } + - { bb: 0, offset: 26, fwdArgRegs: + - { arg: 0, reg: '$x10' } + - { arg: 1, reg: '$x11' } + - { arg: 2, reg: '$x12' } } + - { bb: 0, offset: 30, fwdArgRegs: + - { arg: 0, reg: '$x10' } + - { arg: 1, reg: '$x11' } + - { arg: 2, reg: '$x12' } } + - { bb: 0, offset: 34, fwdArgRegs: + - { arg: 0, reg: '$x10' } + - { arg: 1, reg: '$x11' } + - { arg: 2, reg: '$x12' } } + - { bb: 0, offset: 38, fwdArgRegs: + - { arg: 0, reg: '$x10' } + - { arg: 1, reg: '$x11' } + - { arg: 2, reg: '$x12' } } + - { bb: 0, offset: 42, fwdArgRegs: + - { arg: 0, reg: '$x10' } + - { arg: 1, reg: '$x11' } + - { arg: 2, reg: '$x12' } } + - { bb: 0, offset: 46, fwdArgRegs: + - { arg: 0, reg: '$x10' } + - { arg: 1, reg: '$x11' } + - { arg: 2, reg: '$x12' } } + - { bb: 0, offset: 50, fwdArgRegs: + - { arg: 0, reg: '$x10' } + - { arg: 1, reg: '$x11' } + - { arg: 2, reg: '$x12' } } + - { bb: 0, offset: 54, fwdArgRegs: + - { arg: 0, reg: '$x10' } + - { arg: 1, reg: '$x11' } + - { arg: 2, reg: '$x12' } } +debugValueSubstitutions: [] +constants: [] +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $x1 + + DBG_VALUE $x10, $noreg, !13, !DIExpression(), debug-location !17 + DBG_VALUE $x11, $noreg, !14, !DIExpression(), debug-location !17 + DBG_VALUE $x12, $noreg, !15, !DIExpression(), debug-location !17 + $x2 = frame-setup ADDI $x2, -16 + frame-setup CFI_INSTRUCTION def_cfa_offset 16 + SW killed $x1, $x2, 12, debug-location !17 :: (store (s32) into %stack.0) + frame-setup CFI_INSTRUCTION offset $x1, -4 + DBG_VALUE $noreg, $noreg, !16, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_mul, DW_OP_stack_value), debug-location !17 + $x10 = ADDI $x0, 1, debug-location !17 + DBG_VALUE $x10, $noreg, !13, !DIExpression(DW_OP_LLVM_entry_value, 1), debug-location !17 + $x11 = ADDI $x0, 2, debug-location !17 + DBG_VALUE $x11, $noreg, !14, !DIExpression(DW_OP_LLVM_entry_value, 1), debug-location !17 + $x12 = ADDI $x0, 3, debug-location !17 + DBG_VALUE $x12, $noreg, !15, !DIExpression(DW_OP_LLVM_entry_value, 1), debug-location !17 + PseudoCALL target-flags(riscv-call) @addi_instr, csr_ilp32d_lp64d, implicit-def dead $x1, implicit killed $x10, implicit killed $x11, implicit killed $x12, implicit-def $x2, debug-location !17 + $x10 = ADD $x2, $x0, debug-location !17 + $x11 = ADD $x0, $x0, debug-location !17 + $x12 = ADD $x0, $x2, debug-location !17 + PseudoCALL target-flags(riscv-call) @add_instr, csr_ilp32d_lp64d, implicit-def dead $x1, implicit killed $x10, implicit killed $x11, implicit killed $x12, implicit-def $x2, debug-location !17 + $x10 = ANDI $x0, 5, debug-location !17 + $x11 = ANDI $x0, 6, debug-location !17 + $x12 = ANDI $x2, 0, debug-location !17 + PseudoCALL target-flags(riscv-call) @andi_instr, csr_ilp32d_lp64d, implicit-def dead $x1, implicit killed $x10, implicit killed $x11, implicit killed $x12, implicit-def $x2, debug-location !17 + $x10 = AND $x2, $x0, debug-location !17 + $x11 = AND $x2, $x2, debug-location !17 + $x12 = AND $x0, $x2, debug-location !17 + PseudoCALL target-flags(riscv-call) @and_instr, csr_ilp32d_lp64d, implicit-def dead $x1, implicit killed $x10, implicit killed $x11, implicit killed $x12, implicit-def $x2, debug-location !17 + $x10 = LUI 5, debug-location !17 + $x11 = LUI 6, debug-location !17 + $x12 = LUI 7, debug-location !17 + PseudoCALL target-flags(riscv-call) @lui_instr, csr_ilp32d_lp64d, implicit-def dead $x1, implicit killed $x10, implicit killed $x11, implicit killed $x12, implicit-def $x2, debug-location !17 + $x10 = OR $x2, $x0, debug-location !17 + $x11 = OR $x2, $x2, debug-location !17 + $x12 = OR $x0, $x2, debug-location !17 + PseudoCALL target-flags(riscv-call) @or_instr, csr_ilp32d_lp64d, implicit-def dead $x1, implicit killed $x10, implicit killed $x11, implicit killed $x12, implicit-def $x2, debug-location !17 + $x10 = ORI $x0, 5, debug-location !17 + $x11 = ORI $x2, 0, debug-location !17 + $x12 = XORI $x0, 7, debug-location !17 + PseudoCALL target-flags(riscv-call) @ori_xori_instr, csr_ilp32d_lp64d, implicit-def dead $x1, implicit killed $x10, implicit killed $x11, implicit killed $x12, implicit-def $x2, debug-location !17 + $x10 = SLLI $x2, 0, debug-location !17 + $x11 = SRAI $x0, 6, debug-location !17 + $x12 = SRLI $x0, 7, debug-location !17 + PseudoCALL target-flags(riscv-call) @slli_srli_srai_instr, csr_ilp32d_lp64d, implicit-def dead $x1, implicit killed $x10, implicit killed $x11, implicit killed $x12, implicit-def $x2, debug-location !17 + $x10 = SLL $x2, $x0, debug-location !17 + $x11 = SRL $x0, $x2, debug-location !17 + $x12 = SRA $x0, $x2, debug-location !17 + PseudoCALL target-flags(riscv-call) @sll_srl_sra_instr, csr_ilp32d_lp64d, implicit-def dead $x1, implicit killed $x10, implicit killed $x11, implicit killed $x12, implicit-def $x2, debug-location !17 + $x10 = SUB $x2, $x0, debug-location !17 + $x11 = SUB $x2, $x2, debug-location !17 + $x12 = SUB $x2, $x2, debug-location !17 + PseudoCALL target-flags(riscv-call) @sub_instr, csr_ilp32d_lp64d, implicit-def dead $x1, implicit killed $x10, implicit killed $x11, implicit killed $x12, implicit-def $x2, debug-location !17 + $x10 = XOR $x2, $x0, debug-location !17 + $x11 = XOR $x2, $x2, debug-location !17 + $x12 = XOR $x0, $x2, debug-location !17 + PseudoCALL target-flags(riscv-call) @xor_instr, csr_ilp32d_lp64d, implicit-def dead $x1, implicit killed $x10, implicit killed $x11, implicit killed $x12, implicit-def $x2, debug-location !17 + $x10 = ADDI $x0, 0, debug-location !17 + $x1 = LW $x2, 12, debug-location !17 :: (load (s32) from %stack.0) + $x2 = frame-destroy ADDI $x2, 16, debug-location !17 + PseudoRET implicit killed $x10, debug-location !17 + +...