diff --git a/llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp b/llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp index 5e59172bc1ffba..042776f28bb25f 100644 --- a/llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp +++ b/llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp @@ -95,7 +95,7 @@ static const unsigned GPRDecoderTable[] = { static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/, - const void * /*Decoder*/) { + const MCDisassembler * /*Decoder*/) { if (RegNo > 11) return MCDisassembler::Fail; @@ -108,9 +108,9 @@ static const unsigned GPR32DecoderTable[] = { SBF::W0, SBF::W1, SBF::W2, SBF::W3, SBF::W4, SBF::W5, SBF::W6, SBF::W7, SBF::W8, SBF::W9, SBF::W10, SBF::W11}; -static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo, - uint64_t /*Address*/, - const void * /*Decoder*/) { +static DecodeStatus +DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/, + const MCDisassembler * /*Decoder*/) { if (RegNo > 11) return MCDisassembler::Fail; @@ -120,7 +120,8 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo, } static DecodeStatus decodeMemoryOpValue(MCInst &Inst, unsigned Insn, - uint64_t Address, const void *Decoder) { + uint64_t Address, + const MCDisassembler *Decoder) { unsigned Register = (Insn >> 16) & 0xf; if (Register > 11) return MCDisassembler::Fail; @@ -216,4 +217,4 @@ DecodeStatus SBFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, } typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, - const void *Decoder); + const MCDisassembler *Decoder); diff --git a/llvm/lib/Target/SBF/MCTargetDesc/SBFAsmBackend.cpp b/llvm/lib/Target/SBF/MCTargetDesc/SBFAsmBackend.cpp index 16f13fef91661a..081dfb90fed652 100644 --- a/llvm/lib/Target/SBF/MCTargetDesc/SBFAsmBackend.cpp +++ b/llvm/lib/Target/SBF/MCTargetDesc/SBFAsmBackend.cpp @@ -95,6 +95,11 @@ void SBFAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, } } else { assert(Fixup.getKind() == FK_PCRel_2); + + int64_t ByteOff = (int64_t)Value - 8; + if (ByteOff > INT16_MAX * 8 || ByteOff < INT16_MIN * 8) + report_fatal_error("Branch target out of insn range"); + Value = (uint16_t)((Value - 8) / 8); support::endian::write(&Data[Fixup.getOffset() + 2], Value, Endian); diff --git a/llvm/lib/Target/SBF/MCTargetDesc/SBFMCAsmInfo.cpp b/llvm/lib/Target/SBF/MCTargetDesc/SBFMCAsmInfo.cpp index b62248c3151e96..9c80fc301fc0dc 100644 --- a/llvm/lib/Target/SBF/MCTargetDesc/SBFMCAsmInfo.cpp +++ b/llvm/lib/Target/SBF/MCTargetDesc/SBFMCAsmInfo.cpp @@ -41,6 +41,4 @@ SBFMCAsmInfo::SBFMCAsmInfo(const Triple &TT, const MCTargetOptions &Options) { // section will be parsable, but with odd offsets and // line numbers, etc. CodePointerSize = 8; - - UseIntegratedAssembler = false; } diff --git a/llvm/lib/Target/SBF/MCTargetDesc/SBFMCCodeEmitter.cpp b/llvm/lib/Target/SBF/MCTargetDesc/SBFMCCodeEmitter.cpp index e54284f636b780..24880f0bdc1e43 100644 --- a/llvm/lib/Target/SBF/MCTargetDesc/SBFMCCodeEmitter.cpp +++ b/llvm/lib/Target/SBF/MCTargetDesc/SBFMCCodeEmitter.cpp @@ -31,14 +31,13 @@ using namespace llvm; namespace { class SBFMCCodeEmitter : public MCCodeEmitter { - const MCInstrInfo &MCII; const MCRegisterInfo &MRI; bool IsLittleEndian; public: - SBFMCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri, + SBFMCCodeEmitter(const MCInstrInfo &, const MCRegisterInfo &mri, bool IsLittleEndian) - : MCII(mcii), MRI(mri), IsLittleEndian(IsLittleEndian) {} + : MRI(mri), IsLittleEndian(IsLittleEndian) {} SBFMCCodeEmitter(const SBFMCCodeEmitter &) = delete; void operator=(const SBFMCCodeEmitter &) = delete; ~SBFMCCodeEmitter() override = default; diff --git a/llvm/lib/Target/SBF/SBFAbstractMemberAccess.cpp b/llvm/lib/Target/SBF/SBFAbstractMemberAccess.cpp index 4d36183719b8b1..83e24f7b9393be 100644 --- a/llvm/lib/Target/SBF/SBFAbstractMemberAccess.cpp +++ b/llvm/lib/Target/SBF/SBFAbstractMemberAccess.cpp @@ -123,7 +123,7 @@ class SBFAbstractMemberAccess final { struct CallInfo { uint32_t Kind; uint32_t AccessIndex; - Align RecordAlignment; + MaybeAlign RecordAlignment; MDNode *Metadata; Value *Base; }; @@ -142,9 +142,9 @@ class SBFAbstractMemberAccess final { Module *M = nullptr; static std::map GEPGlobals; - // A map to link preserve_*_access_index instrinsic calls. + // A map to link preserve_*_access_index intrinsic calls. std::map> AIChain; - // A map to hold all the base preserve_*_access_index instrinsic calls. + // A map to hold all the base preserve_*_access_index intrinsic calls. // The base call is not an input of any other preserve_* // intrinsics. std::map BaseAICalls; @@ -176,7 +176,7 @@ class SBFAbstractMemberAccess final { uint32_t &StartBitOffset, uint32_t &EndBitOffset); uint32_t GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy, uint32_t AccessIndex, uint32_t PatchImm, - Align RecordAlignment); + MaybeAlign RecordAlignment); Value *computeBaseAndAccessKey(CallInst *Call, CallInfo &CInfo, std::string &AccessKey, MDNode *&BaseMeta); @@ -410,6 +410,8 @@ bool SBFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, report_fatal_error("Incorrect flag for llvm.bpf.preserve.type.info intrinsic"); if (Flag == SBFCoreSharedInfo::PRESERVE_TYPE_INFO_EXISTENCE) CInfo.AccessIndex = SBFCoreSharedInfo::TYPE_EXISTENCE; + else if (Flag == SBFCoreSharedInfo::PRESERVE_TYPE_INFO_MATCH) + CInfo.AccessIndex = SBFCoreSharedInfo::TYPE_MATCH; else CInfo.AccessIndex = SBFCoreSharedInfo::TYPE_SIZE; return true; @@ -669,10 +671,20 @@ void SBFAbstractMemberAccess::GetStorageBitRange(DIDerivedType *MemberTy, uint32_t &EndBitOffset) { uint32_t MemberBitSize = MemberTy->getSizeInBits(); uint32_t MemberBitOffset = MemberTy->getOffsetInBits(); + + if (RecordAlignment > 8) { + // If the Bits are within an aligned 8-byte, set the RecordAlignment + // to 8, other report the fatal error. + if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64) + report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, " + "requiring too big alignment"); + RecordAlignment = Align(8); + } + uint32_t AlignBits = RecordAlignment.value() * 8; - if (RecordAlignment > 8 || MemberBitSize > AlignBits) + if (MemberBitSize > AlignBits) report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, " - "requiring too big alignment"); + "bitfield size greater than record alignment"); StartBitOffset = MemberBitOffset & ~(AlignBits - 1); if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize)) @@ -685,7 +697,7 @@ uint32_t SBFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy, uint32_t AccessIndex, uint32_t PatchImm, - Align RecordAlignment) { + MaybeAlign RecordAlignment) { if (InfoKind == SBFCoreSharedInfo::FIELD_EXISTENCE) return 1; @@ -701,7 +713,7 @@ uint32_t SBFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, PatchImm += MemberTy->getOffsetInBits() >> 3; } else { unsigned SBitOffset, NextSBitOffset; - GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, + GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset); PatchImm += SBitOffset >> 3; } @@ -720,7 +732,8 @@ uint32_t SBFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, return SizeInBits >> 3; unsigned SBitOffset, NextSBitOffset; - GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset); + GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, + NextSBitOffset); SizeInBits = NextSBitOffset - SBitOffset; if (SizeInBits & (SizeInBits - 1)) report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info"); @@ -780,7 +793,7 @@ uint32_t SBFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, } unsigned SBitOffset, NextSBitOffset; - GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset); + GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset); if (NextSBitOffset - SBitOffset > 64) report_fatal_error("too big field size for llvm.bpf.preserve.field.info"); @@ -811,7 +824,7 @@ uint32_t SBFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, } unsigned SBitOffset, NextSBitOffset; - GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset); + GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset); if (NextSBitOffset - SBitOffset > 64) report_fatal_error("too big field size for llvm.bpf.preserve.field.info"); @@ -1000,7 +1013,8 @@ MDNode *SBFAbstractMemberAccess::computeAccessKey(CallInst *Call, int64_t PatchImm; std::string AccessStr("0"); - if (CInfo.AccessIndex == SBFCoreSharedInfo::TYPE_EXISTENCE) { + if (CInfo.AccessIndex == SBFCoreSharedInfo::TYPE_EXISTENCE || + CInfo.AccessIndex == SBFCoreSharedInfo::TYPE_MATCH) { PatchImm = 1; } else if (CInfo.AccessIndex == SBFCoreSharedInfo::TYPE_SIZE) { // typedef debuginfo type has size 0, get the eventual base type. @@ -1010,8 +1024,11 @@ MDNode *SBFAbstractMemberAccess::computeAccessKey(CallInst *Call, // ENUM_VALUE_EXISTENCE and ENUM_VALUE IsInt32Ret = false; - const auto *CE = cast(Call->getArgOperand(1)); - const GlobalVariable *GV = cast(CE->getOperand(0)); + // The argument could be a global variable or a getelementptr with base to + // a global variable depending on whether the clang option `opaque-options` + // is set or not. + const GlobalVariable *GV = + cast(Call->getArgOperand(1)->stripPointerCasts()); assert(GV->hasInitializer()); const ConstantDataArray *DA = cast(GV->getInitializer()); assert(DA->isString()); diff --git a/llvm/lib/Target/SBF/SBFAdjustOpt.cpp b/llvm/lib/Target/SBF/SBFAdjustOpt.cpp index dd13f7af8c0524..b6f562fbcad73a 100644 --- a/llvm/lib/Target/SBF/SBFAdjustOpt.cpp +++ b/llvm/lib/Target/SBF/SBFAdjustOpt.cpp @@ -259,10 +259,16 @@ bool SBFAdjustOptImpl::serializeICMPCrossBB(BasicBlock &BB) { return false; if (Cond1Op == ICmpInst::ICMP_SGT || Cond1Op == ICmpInst::ICMP_SGE) { - if (Cond2Op != ICmpInst::ICMP_SLT && Cond1Op != ICmpInst::ICMP_SLE) + if (Cond2Op != ICmpInst::ICMP_SLT && Cond2Op != ICmpInst::ICMP_SLE) return false; } else if (Cond1Op == ICmpInst::ICMP_SLT || Cond1Op == ICmpInst::ICMP_SLE) { - if (Cond2Op != ICmpInst::ICMP_SGT && Cond1Op != ICmpInst::ICMP_SGE) + if (Cond2Op != ICmpInst::ICMP_SGT && Cond2Op != ICmpInst::ICMP_SGE) + return false; + } else if (Cond1Op == ICmpInst::ICMP_ULT || Cond1Op == ICmpInst::ICMP_ULE) { + if (Cond2Op != ICmpInst::ICMP_UGT && Cond2Op != ICmpInst::ICMP_UGE) + return false; + } else if (Cond1Op == ICmpInst::ICMP_UGT || Cond1Op == ICmpInst::ICMP_UGE) { + if (Cond2Op != ICmpInst::ICMP_ULT && Cond2Op != ICmpInst::ICMP_ULE) return false; } else { return false; diff --git a/llvm/lib/Target/SBF/SBFAsmPrinter.cpp b/llvm/lib/Target/SBF/SBFAsmPrinter.cpp index 9d238b8b4b5724..5f0dfd5346dd49 100644 --- a/llvm/lib/Target/SBF/SBFAsmPrinter.cpp +++ b/llvm/lib/Target/SBF/SBFAsmPrinter.cpp @@ -35,6 +35,9 @@ using namespace llvm; #define DEBUG_TYPE "asm-printer" extern cl::opt SBFAsmWriterVariant; +static cl::opt SBFEnableBTFEmission( + "sbf-enable-btf-emission", cl::Hidden, cl::init(false), + cl::desc("Enable BTF debuginfo sections to be emitted")); namespace { class SBFAsmPrinter : public AsmPrinter { @@ -62,9 +65,10 @@ bool SBFAsmPrinter::doInitialization(Module &M) { AsmPrinter::doInitialization(M); // Only emit BTF when debuginfo available. - // Unsupported for Solana: https://github.com/solana-labs/llvm-project/issues/37 + // Unsupported for Solana: + // https://github.com/solana-labs/llvm-project/issues/37 if (MAI->doesSupportDebugInformation() && !M.debug_compile_units().empty() && - !TM.getMCSubtargetInfo()->hasFeature(SBF::FeatureSolana) && TM.getTargetTriple().getArch() != Triple::sbf) { + SBFEnableBTFEmission) { BTF = new BTFX::BTFDebug(this); Handlers.push_back(HandlerInfo(std::unique_ptr(BTF), "emit", "Debug Info Emission", "BTF", diff --git a/llvm/lib/Target/SBF/SBFCORE.h b/llvm/lib/Target/SBF/SBFCORE.h index a73789a4bc3537..a6041218bea32b 100644 --- a/llvm/lib/Target/SBF/SBFCORE.h +++ b/llvm/lib/Target/SBF/SBFCORE.h @@ -32,6 +32,7 @@ class SBFCoreSharedInfo { TYPE_SIZE, ENUM_VALUE_EXISTENCE, ENUM_VALUE, + TYPE_MATCH, MAX_FIELD_RELOC_KIND, }; @@ -46,6 +47,7 @@ class SBFCoreSharedInfo { enum PreserveTypeInfo : uint32_t { PRESERVE_TYPE_INFO_EXISTENCE = 0, PRESERVE_TYPE_INFO_SIZE, + PRESERVE_TYPE_INFO_MATCH, MAX_PRESERVE_TYPE_INFO_FLAG, }; diff --git a/llvm/lib/Target/SBF/SBFInstrInfo.cpp b/llvm/lib/Target/SBF/SBFInstrInfo.cpp index 886eb9e9c5fd93..87b42dda5b816f 100644 --- a/llvm/lib/Target/SBF/SBFInstrInfo.cpp +++ b/llvm/lib/Target/SBF/SBFInstrInfo.cpp @@ -192,8 +192,7 @@ bool SBFInstrInfo::analyzeBranch(MachineBasicBlock &MBB, } // If the block has any instructions after a J, delete them. - while (std::next(I) != MBB.end()) - std::next(I)->eraseFromParent(); + MBB.erase(std::next(I), MBB.end()); Cond.clear(); FBB = nullptr; diff --git a/llvm/lib/Target/SBF/SBFInstrInfo.td b/llvm/lib/Target/SBF/SBFInstrInfo.td index 8fc42e2ae96350..dccadd934a9097 100644 --- a/llvm/lib/Target/SBF/SBFInstrInfo.td +++ b/llvm/lib/Target/SBF/SBFInstrInfo.td @@ -389,6 +389,7 @@ def FI_ri let Inst{47-32} = 0; let Inst{31-0} = 0; let SBFClass = SBF_LD; + bit isPseudo = true; } def LD_pseudo diff --git a/llvm/lib/Target/SBF/SBFMISimplifyPatchable.cpp b/llvm/lib/Target/SBF/SBFMISimplifyPatchable.cpp index 50520a613b284f..86a54147a35f78 100644 --- a/llvm/lib/Target/SBF/SBFMISimplifyPatchable.cpp +++ b/llvm/lib/Target/SBF/SBFMISimplifyPatchable.cpp @@ -34,6 +34,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/Debug.h" +#include using namespace llvm; @@ -52,9 +53,12 @@ struct SBFMISimplifyPatchable : public MachineFunctionPass { } private: + std::set SkipInsts; + // Initialize class variables. void initialize(MachineFunction &MFParm); + bool isLoadInst(unsigned Opcode); bool removeLD(); void processCandidate(MachineRegisterInfo *MRI, MachineBasicBlock &MBB, MachineInstr &MI, Register &SrcReg, Register &DstReg, @@ -88,6 +92,12 @@ void SBFMISimplifyPatchable::initialize(MachineFunction &MFParm) { LLVM_DEBUG(dbgs() << "*** SBF simplify patchable insts pass ***\n\n"); } +bool SBFMISimplifyPatchable::isLoadInst(unsigned Opcode) { + return Opcode == SBF::LDD || Opcode == SBF::LDW || Opcode == SBF::LDH || + Opcode == SBF::LDB || Opcode == SBF::LDW32 || Opcode == SBF::LDH32 || + Opcode == SBF::LDB32; +} + void SBFMISimplifyPatchable::checkADDrr(MachineRegisterInfo *MRI, MachineOperand *RelocOp, const GlobalValue *GVal) { const MachineInstr *Inst = RelocOp->getParent(); @@ -229,6 +239,11 @@ void SBFMISimplifyPatchable::processDstReg(MachineRegisterInfo *MRI, void SBFMISimplifyPatchable::processInst(MachineRegisterInfo *MRI, MachineInstr *Inst, MachineOperand *RelocOp, const GlobalValue *GVal) { unsigned Opcode = Inst->getOpcode(); + if (isLoadInst(Opcode)) { + SkipInsts.insert(Inst); + return; + } + if (Opcode == SBF::ADD_rr) checkADDrr(MRI, RelocOp, GVal); else if (Opcode == SBF::SLL_rr) @@ -253,10 +268,10 @@ bool SBFMISimplifyPatchable::removeLD() { } // Ensure the register format is LOAD , , 0 - if (MI.getOpcode() != SBF::LDD && MI.getOpcode() != SBF::LDW && - MI.getOpcode() != SBF::LDH && MI.getOpcode() != SBF::LDB && - MI.getOpcode() != SBF::LDW32 && MI.getOpcode() != SBF::LDH32 && - MI.getOpcode() != SBF::LDB32) + if (!isLoadInst(MI.getOpcode())) + continue; + + if (SkipInsts.find(&MI) != SkipInsts.end()) continue; if (!MI.getOperand(0).isReg() || !MI.getOperand(1).isReg()) diff --git a/llvm/test/CodeGen/SBF/BTF/align.ll b/llvm/test/CodeGen/SBF/BTF/align.ll new file mode 100644 index 00000000000000..dda9223d1dcb68 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/align.ll @@ -0,0 +1,34 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=obj < %s | llvm-readelf -S - | FileCheck %s +; Source: +; int foo() { return 0; } +; Compilation flags: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define dso_local i32 @foo() local_unnamed_addr #0 !dbg !7 { +entry: + ret i32 0, !dbg !12 +} +; CHECK: Name Type Address Off Size ES Flg Lk Inf Al +; CHECK: .BTF PROGBITS 0000000000000000 {{[0-9a-f]+}} {{[0-9a-f]+}} 00 0 0 4 +; CHECK: .BTF.ext PROGBITS 0000000000000000 {{[0-9a-f]+}} {{[0-9a-f]+}} 00 0 0 4 + +attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willreturn "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.0 (https://github.com/llvm/llvm-project.git b1ab2a57b83e4b7224c38b534532500cc90e5b9a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/llvm/align") +!2 = !{i32 7, !"Dwarf Version", i32 4} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 7, !"frame-pointer", i32 2} +!6 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git b1ab2a57b83e4b7224c38b534532500cc90e5b9a)"} +!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{} +!12 = !DILocation(line: 1, column: 13, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/array-1d-char.ll b/llvm/test/CodeGen/SBF/BTF/array-1d-char.ll new file mode 100644 index 00000000000000..65c2b0a540a2fe --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/array-1d-char.ll @@ -0,0 +1,56 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; char a[10]; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global [10 x i8] zeroinitializer, align 1, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 2) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 6 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "char" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=6 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 80, elements: !8) +!7 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!8 = !{!9} +!9 = !DISubrange(count: 10) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} diff --git a/llvm/test/CodeGen/SBF/BTF/array-1d-int.ll b/llvm/test/CodeGen/SBF/BTF/array-1d-int.ll new file mode 100644 index 00000000000000..779aa23fb7e306 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/array-1d-int.ll @@ -0,0 +1,56 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int a[10]; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global [10 x i32] zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 25 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 2) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 5 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=5 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 320, elements: !8) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !{!9} +!9 = !DISubrange(count: 10) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} diff --git a/llvm/test/CodeGen/SBF/BTF/array-2d-int.ll b/llvm/test/CodeGen/SBF/BTF/array-2d-int.ll new file mode 100644 index 00000000000000..5e74ac97fe1dc1 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/array-2d-int.ll @@ -0,0 +1,62 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int a[10][10]; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global [10 x [10 x i32]] zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 80 +; CHECK-NEXT: .long 80 +; CHECK-NEXT: .long 25 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 2) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 3) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 5 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=5 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 3200, elements: !8) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !{!9, !9} +!9 = !DISubrange(count: 10) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} diff --git a/llvm/test/CodeGen/SBF/BTF/array-size-0.ll b/llvm/test/CodeGen/SBF/BTF/array-size-0.ll new file mode 100644 index 00000000000000..fefbfdc4fb616a --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/array-size-0.ll @@ -0,0 +1,58 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct t {}; +; struct t a[10]; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t = type {} + +@a = common dso_local local_unnamed_addr global [10 x %struct.t] zeroinitializer, align 1, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108864 # 0x4000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 2) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 3 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .byte 116 # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=3 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, elements: !8) +!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !3, line: 1, elements: !4) +!8 = !{!9} +!9 = !DISubrange(count: 10) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} diff --git a/llvm/test/CodeGen/SBF/BTF/array-typedef.ll b/llvm/test/CodeGen/SBF/BTF/array-typedef.ll new file mode 100644 index 00000000000000..11bfd4e6bbaf0d --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/array-typedef.ll @@ -0,0 +1,70 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; typedef unsigned _int; +; typedef _int __int; +; __int a[10]; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global [10 x i32] zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!12, !13, !14} +!llvm.ident = !{!15} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 80 +; CHECK-NEXT: .long 80 +; CHECK-NEXT: .long 45 +; CHECK-NEXT: .long 1 # BTF_KIND_TYPEDEF(id = 1) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 7 # BTF_KIND_TYPEDEF(id = 2) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 12 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 4) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 25 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "__int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "_int" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "unsigned int" # string offset=12 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=25 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 3, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 320, elements: !10) +!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !3, line: 2, baseType: !8) +!8 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !3, line: 1, baseType: !9) +!9 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!10 = !{!11} +!11 = !DISubrange(count: 10) +!12 = !{i32 2, !"Dwarf Version", i32 4} +!13 = !{i32 2, !"Debug Info Version", i32 3} +!14 = !{i32 1, !"wchar_size", i32 4} +!15 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} diff --git a/llvm/test/CodeGen/SBF/BTF/binary-format.ll b/llvm/test/CodeGen/SBF/BTF/binary-format.ll new file mode 100644 index 00000000000000..5e84b67c16c1fa --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/binary-format.ll @@ -0,0 +1,56 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=obj -o - %s | llvm-readelf -x ".BTF" -x ".BTF.ext" - | FileCheck -check-prefixes=CHECK,CHECK-EL %s + +; Source code: +; int f(int a) { return a; } +; Compilation flag: +; clang -target bpf -O2 -g -gdwarf-5 -gembed-source -S -emit-llvm t.c + +; Function Attrs: nounwind readnone +define dso_local i32 @f(i32 returned %a) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 %a, metadata !12, metadata !DIExpression()), !dbg !13 + ret i32 %a, !dbg !14 +} + +; CHECK: '.BTF' +; CHECK-EL: 0x00000000 9feb0100 18000000 00000000 30000000 +; CHECK-EL: 0x00000010 30000000 33000000 01000000 00000001 +; CHECK-EL: 0x00000020 04000000 20000001 00000000 0100000d +; CHECK-EL: 0x00000030 01000000 05000000 01000000 07000000 +; CHECK-EL: 0x00000040 0100000c 02000000 00696e74 00610066 +; CHECK: 0x00000050 002e7465 7874002f 746d702f 742e6300 +; CHECK: 0x00000060 696e7420 6628696e 74206129 207b2072 +; CHECK: 0x00000070 65747572 6e20613b 207d00 +; CHECK: '.BTF.ext' +; CHECK-EL: 0x00000000 9feb0100 20000000 00000000 14000000 +; CHECK-EL: 0x00000010 14000000 2c000000 40000000 00000000 +; CHECK-EL: 0x00000020 08000000 09000000 01000000 00000000 +; CHECK-EL: 0x00000030 03000000 10000000 09000000 02000000 +; CHECK-EL: 0x00000040 00000000 0f000000 18000000 00040000 +; CHECK-EL: 0x00000050 00000000 0f000000 18000000 10040000 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "1924f0d78deb326ceb76cd8e9f450775", source: "int f(int a) { return a; }\0A") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 5} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} +!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, isOptimized: true, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 1, type: !10) +!13 = !DILocation(line: 1, column: 11, scope: !7) +!14 = !DILocation(line: 1, column: 16, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/builtin-btf-type-id-2.ll b/llvm/test/CodeGen/SBF/BTF/builtin-btf-type-id-2.ll new file mode 100644 index 00000000000000..af350faab13da6 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/builtin-btf-type-id-2.ll @@ -0,0 +1,73 @@ +; RUN: opt -O2 -mtriple=sbf -S -o %t1 %s +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct s { +; int a; +; }; +; int test(void) { +; return __builtin_btf_type_id(*(const struct s *)0, 1); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +; Function Attrs: nounwind +define dso_local i32 @test() #0 !dbg !7 { +entry: + %0 = call i64 @llvm.bpf.btf.type.id(i32 0, i64 1), !dbg !11, !llvm.preserve.access.index !12 + %conv = trunc i64 %0 to i32, !dbg !11 + ret i32 %conv, !dbg !16 +} + +; CHECK: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 + +; CHECK: .long 16 # BTF_KIND_STRUCT(id = 4) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 18 +; CHECK-NEXT: .long 2 + +; CHECK: .ascii "int" # string offset=1 +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .byte 115 # string offset=16 +; CHECK: .byte 97 # string offset=18 +; CHECK: .byte 48 # string offset=20 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 7 + +; Function Attrs: nounwind readnone +declare i64 @llvm.bpf.btf.type.id(i32, i64) #1 + +attributes #0 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 9783e2098800b954c55ae598a1ce5c4b93444fc0)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/bpf/test") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 9783e2098800b954c55ae598a1ce5c4b93444fc0)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !8, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DILocation(line: 5, column: 10, scope: !7) +!12 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13) +!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 1, size: 32, elements: !14) +!14 = !{!15} +!15 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !13, file: !1, line: 2, baseType: !10, size: 32) +!16 = !DILocation(line: 5, column: 3, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/builtin-btf-type-id.ll b/llvm/test/CodeGen/SBF/BTF/builtin-btf-type-id.ll new file mode 100644 index 00000000000000..e7ea449e1ae2cd --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/builtin-btf-type-id.ll @@ -0,0 +1,151 @@ +; RUN: opt -O2 -mtriple=sbf %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; static int (*bpf_log)(unsigned long tid, void *data, int data_size) = (void *)999; +; struct { +; char f1[100]; +; typeof(3) f2; +; } tmp__abc = {1, 3}; +; void prog1() { +; bpf_log(__builtin_btf_type_id(tmp__abc, 0), &tmp__abc, sizeof(tmp__abc)); +; } +; void prog2() { +; bpf_log(__builtin_btf_type_id(&tmp__abc, 0), &tmp__abc, sizeof(tmp__abc)); +; } +; void prog3() { +; bpf_log(__builtin_btf_type_id(tmp__abc.f1[3], 1), &tmp__abc, sizeof(tmp__abc)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +@tmp__abc = dso_local global { <{ i8, i8, [98 x i8] }>, i32 } { <{ i8, i8, [98 x i8] }> <{ i8 1, i8 3, [98 x i8] zeroinitializer }>, i32 0 }, align 4, !dbg !0 +@bpf_log = internal global i32 (i64, i8*, i32)* inttoptr (i64 999 to i32 (i64, i8*, i32)*), align 8, !dbg !17 + +; Function Attrs: nounwind +define dso_local void @prog1() #0 !dbg !28 { +entry: + %0 = load i32 (i64, i8*, i32)*, i32 (i64, i8*, i32)** @bpf_log, align 8, !dbg !31, !tbaa !32 + %1 = call i64 @llvm.bpf.btf.type.id(i32 0, i64 0), !dbg !36, !llvm.preserve.access.index !7 + %call = call i32 %0(i64 %1, i8* getelementptr inbounds ({ <{ i8, i8, [98 x i8] }>, i32 }, { <{ i8, i8, [98 x i8] }>, i32 }* @tmp__abc, i32 0, i32 0, i32 0), i32 104), !dbg !31 + ret void, !dbg !37 +} + +; Function Attrs: nounwind readnone +declare i64 @llvm.bpf.btf.type.id(i32, i64) #1 + +; Function Attrs: nounwind +define dso_local void @prog2() #0 !dbg !38 { +entry: + %0 = load i32 (i64, i8*, i32)*, i32 (i64, i8*, i32)** @bpf_log, align 8, !dbg !39, !tbaa !32 + %1 = call i64 @llvm.bpf.btf.type.id(i32 1, i64 0), !dbg !40, !llvm.preserve.access.index !6 + %call = call i32 %0(i64 %1, i8* getelementptr inbounds ({ <{ i8, i8, [98 x i8] }>, i32 }, { <{ i8, i8, [98 x i8] }>, i32 }* @tmp__abc, i32 0, i32 0, i32 0), i32 104), !dbg !39 + ret void, !dbg !41 +} + +; Function Attrs: nounwind +define dso_local void @prog3() #0 !dbg !42 { +entry: + %0 = load i32 (i64, i8*, i32)*, i32 (i64, i8*, i32)** @bpf_log, align 8, !dbg !43, !tbaa !32 + %1 = call i64 @llvm.bpf.btf.type.id(i32 2, i64 1), !dbg !44, !llvm.preserve.access.index !11 + %call = call i32 %0(i64 %1, i8* getelementptr inbounds ({ <{ i8, i8, [98 x i8] }>, i32 }, { <{ i8, i8, [98 x i8] }>, i32 }* @tmp__abc, i32 0, i32 0, i32 0), i32 104), !dbg !43 + ret void, !dbg !45 +} + +; CHECK-LABEL: prog1 +; CHECK: lddw r1, 3 +; CHECK-LABEL: prog2 +; CHECK: lddw r1, 10 +; CHECK-LABEL: prog3 +; CHECK: lddw r1, 4 + +; CHECK: .long 0 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 104 +; CHECK-NEXT: .long 13 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 800 # 0x320 +; CHECK: .long 19 # BTF_KIND_INT(id = 4) +; CHECK: .long 0 # BTF_KIND_PTR(id = 10) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 + +; CHECK: .ascii ".text" # string offset=7 +; CHECK: .ascii "f1" # string offset=13 +; CHECK: .ascii "f2" # string offset=16 +; CHECK: .ascii "char" # string offset=19 +; CHECK: .byte 48 # string offset=48 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 7 # Field reloc section string offset=7 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 7 + +attributes #0 = { nounwind "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!24, !25, !26} +!llvm.ident = !{!27} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "tmp__abc", scope: !2, file: !3, line: 5, type: !7, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git 630c2da0e967e27e2a4c678dfc6e452a74141880)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !16, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!4 = !{} +!5 = !{!6, !11} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !3, line: 2, size: 832, elements: !8) +!8 = !{!9, !14} +!9 = !DIDerivedType(tag: DW_TAG_member, name: "f1", scope: !7, file: !3, line: 3, baseType: !10, size: 800) +!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, size: 800, elements: !12) +!11 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!12 = !{!13} +!13 = !DISubrange(count: 100) +!14 = !DIDerivedType(tag: DW_TAG_member, name: "f2", scope: !7, file: !3, line: 4, baseType: !15, size: 32, offset: 800) +!15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!16 = !{!0, !17} +!17 = !DIGlobalVariableExpression(var: !18, expr: !DIExpression()) +!18 = distinct !DIGlobalVariable(name: "bpf_log", scope: !2, file: !3, line: 1, type: !19, isLocal: true, isDefinition: true) +!19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64) +!20 = !DISubroutineType(types: !21) +!21 = !{!15, !22, !23, !15} +!22 = !DIBasicType(name: "long unsigned int", size: 64, encoding: DW_ATE_unsigned) +!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!24 = !{i32 7, !"Dwarf Version", i32 4} +!25 = !{i32 2, !"Debug Info Version", i32 3} +!26 = !{i32 1, !"wchar_size", i32 4} +!27 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git 630c2da0e967e27e2a4c678dfc6e452a74141880)"} +!28 = distinct !DISubprogram(name: "prog1", scope: !3, file: !3, line: 6, type: !29, scopeLine: 6, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) +!29 = !DISubroutineType(types: !30) +!30 = !{null} +!31 = !DILocation(line: 7, column: 3, scope: !28) +!32 = !{!33, !33, i64 0} +!33 = !{!"any pointer", !34, i64 0} +!34 = !{!"omnipotent char", !35, i64 0} +!35 = !{!"Simple C/C++ TBAA"} +!36 = !DILocation(line: 7, column: 11, scope: !28) +!37 = !DILocation(line: 8, column: 1, scope: !28) +!38 = distinct !DISubprogram(name: "prog2", scope: !3, file: !3, line: 9, type: !29, scopeLine: 9, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) +!39 = !DILocation(line: 10, column: 3, scope: !38) +!40 = !DILocation(line: 10, column: 11, scope: !38) +!41 = !DILocation(line: 11, column: 1, scope: !38) +!42 = distinct !DISubprogram(name: "prog3", scope: !3, file: !3, line: 12, type: !29, scopeLine: 12, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) +!43 = !DILocation(line: 13, column: 3, scope: !42) +!44 = !DILocation(line: 13, column: 11, scope: !42) +!45 = !DILocation(line: 14, column: 1, scope: !42) diff --git a/llvm/test/CodeGen/SBF/BTF/char-no-debuginfo.ll b/llvm/test/CodeGen/SBF/BTF/char-no-debuginfo.ll new file mode 100644 index 00000000000000..befa09ec0c7bc5 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/char-no-debuginfo.ll @@ -0,0 +1,30 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int g __attribute__((section("maps"))) = 5; +; int test() { return g; } +; Compilation flag: +; clang -target bpf -O2 -S -emit-llvm t.c + +@g = dso_local local_unnamed_addr global i32 5, section "maps", align 4 + +; Function Attrs: norecurse nounwind readonly +define dso_local i32 @test() local_unnamed_addr #0 { + %1 = load i32, i32* @g, align 4, !tbaa !2 + ret i32 %1 +} + +; CHECK-NOT: .section .BTF +; CHECK-NOT: .section .BTF.ext + +attributes #0 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 8.0.20181009 "} +!2 = !{!3, !3, i64 0} +!3 = !{!"int", !4, i64 0} +!4 = !{!"omnipotent char", !5, i64 0} +!5 = !{!"Simple C/C++ TBAA"} diff --git a/llvm/test/CodeGen/SBF/BTF/char.ll b/llvm/test/CodeGen/SBF/BTF/char.ll new file mode 100644 index 00000000000000..7b3da2984098ae --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/char.ll @@ -0,0 +1,41 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; char a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i8 0, align 1, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "char" # string offset=1 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/double.ll b/llvm/test/CodeGen/SBF/BTF/double.ll new file mode 100644 index 00000000000000..46f287c10bb33e --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/double.ll @@ -0,0 +1,57 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; double a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = dso_local local_unnamed_addr global double 0.000000e+00, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 15 +; [1] double, size=8 bytes (64 bits) +; CHECK-NEXT: .long 1 # BTF_KIND_FLOAT(id = 1) +; CHECK-NEXT: .long 268435456 # 0x10000000 +; CHECK-NEXT: .long 8 +; [2] a, type=double (1), global +; CHECK-NEXT: .long 8 # BTF_KIND_VAR(id = 2) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; [3] .bss, 1 var, {a, offset=&a, size=8 bytes} +; CHECK-NEXT: .long 10 # BTF_KIND_DATASEC(id = 3) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long a +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "double" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=8 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".bss" # string offset=10 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 11.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float) +!7 = !{i32 7, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 11.0.0 "} diff --git a/llvm/test/CodeGen/SBF/BTF/empty-btf.ll b/llvm/test/CodeGen/SBF/BTF/empty-btf.ll new file mode 100644 index 00000000000000..1ae3a307422f19 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/empty-btf.ll @@ -0,0 +1,21 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int test(int arg) { return arg; } +; Compilation flag: +; clang -target bpf -O2 -S -emit-llvm t.c + +; Function Attrs: norecurse nounwind readnone +define dso_local i32 @test(i32 returned) local_unnamed_addr #0 { + ret i32 %0 +} + +; CHECK-NOT: BTF + +attributes #0 = { norecurse nounwind readnone } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 8.0.20181009 "} diff --git a/llvm/test/CodeGen/SBF/BTF/enum-basic.ll b/llvm/test/CodeGen/SBF/BTF/enum-basic.ll new file mode 100644 index 00000000000000..65f64944a02c14 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/enum-basic.ll @@ -0,0 +1,50 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; enum { A = -1, B = 2 } a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32 0, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # BTF_KIND_ENUM(id = 1) +; CHECK-NEXT: .long 2248146946 # 0x86000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long -1 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .byte 65 # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 66 # string offset=3 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !10, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{!5} +!5 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !3, line: 1, baseType: !6, size: 32, elements: !7) +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = !{!8, !9} +!8 = !DIEnumerator(name: "A", value: -1) +!9 = !DIEnumerator(name: "B", value: 2) +!10 = !{!0} +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/extern-builtin.ll b/llvm/test/CodeGen/SBF/BTF/extern-builtin.ll new file mode 100644 index 00000000000000..294b65fbae5056 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/extern-builtin.ll @@ -0,0 +1,90 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; Note that llvm.bpd.load does not apply to SBF, delete eventually. +: XFAIL: * +; Source code: +; unsigned long long load_byte(void *skb, +; unsigned long long off) asm("llvm.bpf.load.byte"); +; unsigned long long test(void *skb) { +; return load_byte(skb, 10); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +; Function Attrs: nounwind readonly +define dso_local i64 @test(i8* readonly %skb) local_unnamed_addr #0 !dbg !13 { +entry: + call void @llvm.dbg.value(metadata i8* %skb, metadata !17, metadata !DIExpression()), !dbg !18 + %call = tail call i64 @llvm.bpf.load.byte(i8* %skb, i64 10), !dbg !19 + ret i64 %call, !dbg !20 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 60 +; CHECK-NEXT: .long 60 +; CHECK-NEXT: .long 78 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 2) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 5 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 64 # 0x40 +; CHECK-NEXT: .long 28 # BTF_KIND_FUNC(id = 4) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "skb" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "long long unsigned int" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test" # string offset=28 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=33 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/extern/test.c" # string offset=39 +; CHECK-NEXT: .byte 0 + +; Function Attrs: nounwind readonly +declare !dbg !4 i64 @llvm.bpf.load.byte(i8*, i64) #1 +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readonly } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 907019d835895443b198afcd992c42c9d3478fdf)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/extern") +!2 = !{} +!3 = !{!4} +!4 = !DISubprogram(name: "load_byte", linkageName: "llvm.bpf.load.byte", scope: !1, file: !1, line: 1, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7, !8, !7} +!7 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned) +!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!9 = !{i32 7, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 907019d835895443b198afcd992c42c9d3478fdf)"} +!13 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !14, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !16) +!14 = !DISubroutineType(types: !15) +!15 = !{!7, !8} +!16 = !{!17} +!17 = !DILocalVariable(name: "skb", arg: 1, scope: !13, file: !1, line: 3, type: !8) +!18 = !DILocation(line: 0, scope: !13) +!19 = !DILocation(line: 4, column: 10, scope: !13) +!20 = !DILocation(line: 4, column: 3, scope: !13) diff --git a/llvm/test/CodeGen/SBF/BTF/extern-func-arg.ll b/llvm/test/CodeGen/SBF/BTF/extern-func-arg.ll new file mode 100644 index 00000000000000..8196d60c527e48 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/extern-func-arg.ll @@ -0,0 +1,78 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; extern int global_func(char arg); +; int test() { return global_func(0); } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +; Function Attrs: nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !13 { +entry: + %call = tail call i32 @global_func(i8 signext 0) #2, !dbg !16 + ret i32 %call, !dbg !17 +} + +; CHECK: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 88 +; CHECK-NEXT: .long 88 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 4) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 55 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 60 # BTF_KIND_FUNC(id = 6) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 4 +; CHECK: .ascii "int" # string offset=1 +; CHECK: .ascii "test" # string offset=5 +; CHECK: .ascii "char" # string offset=55 +; CHECK: .ascii "global_func" # string offset=60 + +declare !dbg !4 dso_local i32 @global_func(i8 signext) local_unnamed_addr #1 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 987c5665e81822b32c895fd0c97a9a084b0d3106)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/extern") +!2 = !{} +!3 = !{!4} +!4 = !DISubprogram(name: "global_func", scope: !1, file: !1, line: 1, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7, !8} +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!9 = !{i32 7, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 987c5665e81822b32c895fd0c97a9a084b0d3106)"} +!13 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 2, type: !14, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!14 = !DISubroutineType(types: !15) +!15 = !{!7} +!16 = !DILocation(line: 2, column: 21, scope: !13) +!17 = !DILocation(line: 2, column: 14, scope: !13) diff --git a/llvm/test/CodeGen/SBF/BTF/extern-func-ptr.ll b/llvm/test/CodeGen/SBF/BTF/extern-func-ptr.ll new file mode 100644 index 00000000000000..90dffc95a1e309 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/extern-func-ptr.ll @@ -0,0 +1,75 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; extern int do_work(int) __attribute__((section(".callback_fn"))); +; long bpf_helper(void *callback_fn); +; long prog() { +; return bpf_helper(&do_work); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +; Function Attrs: nounwind +define dso_local i64 @prog() local_unnamed_addr #0 !dbg !7 { +entry: + %call = tail call i64 @bpf_helper(i8* bitcast (i32 (i32)* @do_work to i8*)) #2, !dbg !11 + ret i64 %call, !dbg !12 +} + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 4) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 51 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 55 # BTF_KIND_FUNC(id = 6) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 4 + +; CHECK: .long 74 # BTF_KIND_DATASEC(id = 10) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long do_work +; CHECK-NEXT: .long 0 + +; CHECK: .ascii "int" # string offset=51 +; CHECK: .ascii "do_work" # string offset=55 +; CHECK: .ascii ".callback_fn" # string offset=74 + +declare !dbg !13 dso_local i64 @bpf_helper(i8*) local_unnamed_addr #1 + +declare !dbg !17 dso_local i32 @do_work(i32) #1 section ".callback_fn" + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git aa382ed8a38d5efa118e1b2617544f5c253658a9)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/btf/core") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git aa382ed8a38d5efa118e1b2617544f5c253658a9)"} +!7 = distinct !DISubprogram(name: "prog", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed) +!11 = !DILocation(line: 4, column: 12, scope: !7) +!12 = !DILocation(line: 4, column: 5, scope: !7) +!13 = !DISubprogram(name: "bpf_helper", scope: !1, file: !1, line: 2, type: !14, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!14 = !DISubroutineType(types: !15) +!15 = !{!10, !16} +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!17 = !DISubprogram(name: "do_work", scope: !1, file: !1, line: 1, type: !18, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!18 = !DISubroutineType(types: !19) +!19 = !{!20, !20} +!20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) diff --git a/llvm/test/CodeGen/SBF/BTF/extern-global-var.ll b/llvm/test/CodeGen/SBF/BTF/extern-global-var.ll new file mode 100644 index 00000000000000..0388067026bbf2 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/extern-global-var.ll @@ -0,0 +1,68 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; extern char a; +; int foo() { return a; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@a = external dso_local local_unnamed_addr global i8, align 1 + +; Function Attrs: norecurse nounwind readonly +define dso_local i32 @foo() local_unnamed_addr #0 !dbg !7 { + %1 = load i8, i8* @a, align 1, !dbg !11, !tbaa !12 + %2 = sext i8 %1 to i32, !dbg !11 + ret i32 %2, !dbg !15 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/home/yhs/work/tests/llvm/bug/test.c" # string offset=15 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.20181009 "} +!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DILocation(line: 2, column: 20, scope: !7) +!12 = !{!13, !13, i64 0} +!13 = !{!"omnipotent char", !14, i64 0} +!14 = !{!"Simple C/C++ TBAA"} +!15 = !DILocation(line: 2, column: 13, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/extern-var-func-weak-section.ll b/llvm/test/CodeGen/SBF/BTF/extern-var-func-weak-section.ll new file mode 100644 index 00000000000000..62a7ac77e88a9e --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/extern-var-func-weak-section.ll @@ -0,0 +1,96 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; extern int global_func(char c) __attribute__((weak, section("abc"))); +; int test() { +; return global_func(0); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +; Function Attrs: nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !13 { +entry: + %call = tail call i32 @global_func(i8 signext 0) #2, !dbg !16 + ret i32 %call, !dbg !17 +} +declare !dbg !4 extern_weak dso_local i32 @global_func(i8 signext) local_unnamed_addr #1 section "abc" + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 112 +; CHECK-NEXT: .long 112 +; CHECK-NEXT: .long 76 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 4) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 55 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 60 # BTF_KIND_FUNC(id = 6) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 72 # BTF_KIND_DATASEC(id = 7) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long global_func +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/extern/test.c" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=55 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "global_func" # string offset=60 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "abc" # string offset=72 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 71a9518c93fe1dce9611c24bc707e5baf1f39f0d)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/extern") +!2 = !{} +!3 = !{!4} +!4 = !DISubprogram(name: "global_func", scope: !1, file: !1, line: 1, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7, !8} +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!9 = !{i32 7, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 71a9518c93fe1dce9611c24bc707e5baf1f39f0d)"} +!13 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 2, type: !14, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!14 = !DISubroutineType(types: !15) +!15 = !{!7} +!16 = !DILocation(line: 3, column: 11, scope: !13) +!17 = !DILocation(line: 3, column: 4, scope: !13) diff --git a/llvm/test/CodeGen/SBF/BTF/extern-var-func-weak.ll b/llvm/test/CodeGen/SBF/BTF/extern-var-func-weak.ll new file mode 100644 index 00000000000000..d4ea7b139e7026 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/extern-var-func-weak.ll @@ -0,0 +1,89 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; extern int global_func(char c) __attribute__((weak)); +; int test() { +; return global_func(0); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +; Function Attrs: nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !13 { +entry: + %call = tail call i32 @global_func(i8 signext 0) #2, !dbg !16 + ret i32 %call, !dbg !17 +} +declare !dbg !4 extern_weak dso_local i32 @global_func(i8 signext) local_unnamed_addr #1 + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 88 +; CHECK-NEXT: .long 88 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 4) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 55 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 60 # BTF_KIND_FUNC(id = 6) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/extern/test.c" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=55 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "global_func" # string offset=60 +; CHECK-NEXT: .byte 0 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 71a9518c93fe1dce9611c24bc707e5baf1f39f0d)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/extern") +!2 = !{} +!3 = !{!4} +!4 = !DISubprogram(name: "global_func", scope: !1, file: !1, line: 1, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7, !8} +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!9 = !{i32 7, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 71a9518c93fe1dce9611c24bc707e5baf1f39f0d)"} +!13 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 2, type: !14, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!14 = !DISubroutineType(types: !15) +!15 = !{!7} +!16 = !DILocation(line: 3, column: 11, scope: !13) +!17 = !DILocation(line: 3, column: 4, scope: !13) diff --git a/llvm/test/CodeGen/SBF/BTF/extern-var-func.ll b/llvm/test/CodeGen/SBF/BTF/extern-var-func.ll new file mode 100644 index 00000000000000..d7e819b3d07b7e --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/extern-var-func.ll @@ -0,0 +1,90 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; extern int global_func(char c); +; int test() { +; return global_func(0); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +; Function Attrs: nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !13 { +entry: + %call = tail call i32 @global_func(i8 signext 0) #2, !dbg !16 + ret i32 %call, !dbg !17 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 88 +; CHECK-NEXT: .long 88 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 4) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 55 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 60 # BTF_KIND_FUNC(id = 6) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/extern/test.c" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=55 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "global_func" # string offset=60 +; CHECK-NEXT: .byte 0 + +declare !dbg !4 dso_local i32 @global_func(i8 signext) local_unnamed_addr #1 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 77e5c60f04c4597ba5704d3cee61c6d359404ccd)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/extern") +!2 = !{} +!3 = !{!4} +!4 = !DISubprogram(name: "global_func", scope: !1, file: !1, line: 1, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7, !8} +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 77e5c60f04c4597ba5704d3cee61c6d359404ccd)"} +!13 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 2, type: !14, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!14 = !DISubroutineType(types: !15) +!15 = !{!7} +!16 = !DILocation(line: 3, column: 10, scope: !13) +!17 = !DILocation(line: 3, column: 3, scope: !13) diff --git a/llvm/test/CodeGen/SBF/BTF/extern-var-section.ll b/llvm/test/CodeGen/SBF/BTF/extern-var-section.ll new file mode 100644 index 00000000000000..3b078ac25b00de --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/extern-var-section.ll @@ -0,0 +1,121 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; extern int global_func(char c) __attribute__((section("abc"))); +; extern char ch __attribute__((section("abc"))); +; int test() { +; return global_func(0) + ch; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@ch = external dso_local local_unnamed_addr global i8, section "abc", align 1, !dbg !0 + +; Function Attrs: nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !16 { +entry: + %call = tail call i32 @global_func(i8 signext 0) #2, !dbg !19 + %0 = load i8, i8* @ch, align 1, !dbg !20, !tbaa !21 + %conv = sext i8 %0 to i32, !dbg !20 + %add = add nsw i32 %call, %conv, !dbg !24 + ret i32 %add, !dbg !25 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 140 +; CHECK-NEXT: .long 140 +; CHECK-NEXT: .long 79 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 4) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 55 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 60 # BTF_KIND_FUNC(id = 6) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 72 # BTF_KIND_VAR(id = 7) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 75 # BTF_KIND_DATASEC(id = 8) +; CHECK-NEXT: .long 251658242 # 0xf000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long global_func +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long ch +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/extern/test.c" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=55 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "global_func" # string offset=60 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "ch" # string offset=72 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "abc" # string offset=75 +; CHECK-NEXT: .byte 0 + +declare !dbg !6 dso_local i32 @global_func(i8 signext) local_unnamed_addr #1 section "abc" + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!12, !13, !14} +!llvm.ident = !{!15} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "ch", scope: !2, file: !3, line: 2, type: !10, isLocal: false, isDefinition: false) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 0ad024346185b3f0b5167438e126568982b1168d)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !11, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/extern") +!4 = !{} +!5 = !{!6} +!6 = !DISubprogram(name: "global_func", scope: !3, file: !3, line: 1, type: !7, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !4) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !10} +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!11 = !{!0} +!12 = !{i32 2, !"Dwarf Version", i32 4} +!13 = !{i32 2, !"Debug Info Version", i32 3} +!14 = !{i32 1, !"wchar_size", i32 4} +!15 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 0ad024346185b3f0b5167438e126568982b1168d)"} +!16 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 3, type: !17, scopeLine: 3, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) +!17 = !DISubroutineType(types: !18) +!18 = !{!9} +!19 = !DILocation(line: 4, column: 10, scope: !16) +!20 = !DILocation(line: 4, column: 27, scope: !16) +!21 = !{!22, !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 4, column: 25, scope: !16) +!25 = !DILocation(line: 4, column: 3, scope: !16) diff --git a/llvm/test/CodeGen/SBF/BTF/extern-var-struct-weak.ll b/llvm/test/CodeGen/SBF/BTF/extern-var-struct-weak.ll new file mode 100644 index 00000000000000..78100b5730e563 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/extern-var-struct-weak.ll @@ -0,0 +1,100 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; typedef struct t1 { int f1; } __t1; +; extern __t1 global __attribute__((weak)); +; int test() { return global.f1; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +%struct.t1 = type { i32 } + +@global = extern_weak dso_local local_unnamed_addr global %struct.t1, align 4, !dbg !0 +; Function Attrs: norecurse nounwind readonly +define dso_local i32 @test() local_unnamed_addr #0 !dbg !15 { +entry: + %0 = load i32, i32* getelementptr (%struct.t1, %struct.t1* @global, i64 0, i32 0), align 4, !dbg !18, !tbaa !19 + ret i32 %0, !dbg !24 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 92 +; CHECK-NEXT: .long 92 +; CHECK-NEXT: .long 73 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 55 # BTF_KIND_TYPEDEF(id = 4) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 60 # BTF_KIND_STRUCT(id = 5) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 63 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 66 # BTF_KIND_VAR(id = 6) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/extern/test.c" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__t1" # string offset=55 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "t1" # string offset=60 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "f1" # string offset=63 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "global" # string offset=66 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "global", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: false) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 71a9518c93fe1dce9611c24bc707e5baf1f39f0d)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/extern") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "__t1", file: !3, line: 1, baseType: !7) +!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 1, size: 32, elements: !8) +!8 = !{!9} +!9 = !DIDerivedType(tag: DW_TAG_member, name: "f1", scope: !7, file: !3, line: 1, baseType: !10, size: 32) +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{i32 7, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 71a9518c93fe1dce9611c24bc707e5baf1f39f0d)"} +!15 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 3, type: !16, scopeLine: 3, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) +!16 = !DISubroutineType(types: !17) +!17 = !{!10} +!18 = !DILocation(line: 3, column: 28, scope: !15) +!19 = !{!20, !21, i64 0} +!20 = !{!"t1", !21, i64 0} +!21 = !{!"int", !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 3, column: 14, scope: !15) diff --git a/llvm/test/CodeGen/SBF/BTF/extern-var-struct.ll b/llvm/test/CodeGen/SBF/BTF/extern-var-struct.ll new file mode 100644 index 00000000000000..45988465b9d66c --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/extern-var-struct.ll @@ -0,0 +1,101 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; typedef struct t1 { int f1; } __t1; +; extern __t1 global; +; int test() { return global.f1; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +%struct.t1 = type { i32 } + +@global = external dso_local local_unnamed_addr global %struct.t1, align 4, !dbg !0 + +; Function Attrs: norecurse nounwind readonly +define dso_local i32 @test() local_unnamed_addr #0 !dbg !15 { +entry: + %0 = load i32, i32* getelementptr inbounds (%struct.t1, %struct.t1* @global, i64 0, i32 0), align 4, !dbg !18, !tbaa !19 + ret i32 %0, !dbg !24 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 92 +; CHECK-NEXT: .long 92 +; CHECK-NEXT: .long 73 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 55 # BTF_KIND_TYPEDEF(id = 4) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 60 # BTF_KIND_STRUCT(id = 5) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 63 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 66 # BTF_KIND_VAR(id = 6) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/extern/test.c" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__t1" # string offset=55 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "t1" # string offset=60 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "f1" # string offset=63 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "global" # string offset=66 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "global", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: false) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 2798d63180f4cc873bdaf689705fd4f9521ae89f)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/extern") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "__t1", file: !3, line: 1, baseType: !7) +!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 1, size: 32, elements: !8) +!8 = !{!9} +!9 = !DIDerivedType(tag: DW_TAG_member, name: "f1", scope: !7, file: !3, line: 1, baseType: !10, size: 32) +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 2798d63180f4cc873bdaf689705fd4f9521ae89f)"} +!15 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 4, type: !16, scopeLine: 4, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) +!16 = !DISubroutineType(types: !17) +!17 = !{!10} +!18 = !DILocation(line: 4, column: 28, scope: !15) +!19 = !{!20, !21, i64 0} +!20 = !{!"t1", !21, i64 0} +!21 = !{!"int", !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 4, column: 14, scope: !15) diff --git a/llvm/test/CodeGen/SBF/BTF/extern-var-weak-section.ll b/llvm/test/CodeGen/SBF/BTF/extern-var-weak-section.ll new file mode 100644 index 00000000000000..39a1dcf9241a57 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/extern-var-weak-section.ll @@ -0,0 +1,119 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; extern int global_func(char c) __attribute__((weak, section("abc"))); +; extern char ch __attribute__((weak, section("abc"))); +; int test() { +; return global_func(0) + ch; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@ch = extern_weak dso_local local_unnamed_addr global i8, section "abc", align 1, !dbg !0 +; Function Attrs: nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !16 { +entry: + %call = tail call i32 @global_func(i8 signext 0) #2, !dbg !19 + %0 = load i8, i8* @ch, align 1, !dbg !20, !tbaa !21 + %conv = sext i8 %0 to i32, !dbg !20 + %add = add nsw i32 %call, %conv, !dbg !24 + ret i32 %add, !dbg !25 +} +declare !dbg !6 extern_weak dso_local i32 @global_func(i8 signext) local_unnamed_addr #1 section "abc" + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 140 +; CHECK-NEXT: .long 140 +; CHECK-NEXT: .long 79 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 4) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 55 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 60 # BTF_KIND_FUNC(id = 6) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 72 # BTF_KIND_VAR(id = 7) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 75 # BTF_KIND_DATASEC(id = 8) +; CHECK-NEXT: .long 251658242 # 0xf000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long global_func +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long ch +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/extern/test.c" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=55 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "global_func" # string offset=60 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "ch" # string offset=72 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "abc" # string offset=75 +; CHECK-NEXT: .byte 0 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!12, !13, !14} +!llvm.ident = !{!15} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "ch", scope: !2, file: !3, line: 2, type: !10, isLocal: false, isDefinition: false) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 71a9518c93fe1dce9611c24bc707e5baf1f39f0d)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !11, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/extern") +!4 = !{} +!5 = !{!6} +!6 = !DISubprogram(name: "global_func", scope: !3, file: !3, line: 1, type: !7, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !4) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !10} +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!11 = !{!0} +!12 = !{i32 7, !"Dwarf Version", i32 4} +!13 = !{i32 2, !"Debug Info Version", i32 3} +!14 = !{i32 1, !"wchar_size", i32 4} +!15 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 71a9518c93fe1dce9611c24bc707e5baf1f39f0d)"} +!16 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 3, type: !17, scopeLine: 3, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) +!17 = !DISubroutineType(types: !18) +!18 = !{!9} +!19 = !DILocation(line: 4, column: 10, scope: !16) +!20 = !DILocation(line: 4, column: 27, scope: !16) +!21 = !{!22, !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 4, column: 25, scope: !16) +!25 = !DILocation(line: 4, column: 3, scope: !16) diff --git a/llvm/test/CodeGen/SBF/BTF/filename.ll b/llvm/test/CodeGen/SBF/BTF/filename.ll new file mode 100644 index 00000000000000..170e0793531753 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/filename.ll @@ -0,0 +1,82 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int test() { return 0; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +; Function Attrs: norecurse nounwind readnone uwtable +define dso_local i32 @test() local_unnamed_addr #0 !dbg !7 { + ret i32 0, !dbg !11 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 35 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/home/yhs/ttmp/t.c" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 8 # FuncInfo +; CHECK-NEXT: .long 10 # FuncInfo section string offset=10 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin{{[0-9]+}} +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 16 # LineInfo +; CHECK-NEXT: .long 10 # LineInfo section string offset=10 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1038 # Line 1 Col 14 + +attributes #0 = { norecurse nounwind readnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "/home/yhs/ttmp/t.c", directory: "/home/yhs/ttmp") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.20181009 "} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DILocation(line: 1, column: 14, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/float.ll b/llvm/test/CodeGen/SBF/BTF/float.ll new file mode 100644 index 00000000000000..df2e19d2ccb8f7 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/float.ll @@ -0,0 +1,57 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; float a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = dso_local local_unnamed_addr global float 0.000000e+00, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 14 +; [1] float, size=4 bytes (32 bits) +; CHECK-NEXT: .long 1 # BTF_KIND_FLOAT(id = 1) +; CHECK-NEXT: .long 268435456 # 0x10000000 +; CHECK-NEXT: .long 4 +; [2] a, type=float (1), global +; CHECK-NEXT: .long 7 # BTF_KIND_VAR(id = 2) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; [3] .bss, 1 var, {a, offset=&a, size=4 bytes} +; CHECK-NEXT: .long 9 # BTF_KIND_DATASEC(id = 3) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long a +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "float" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".bss" # string offset=9 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 11.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float) +!7 = !{i32 7, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 11.0.0 "} diff --git a/llvm/test/CodeGen/SBF/BTF/func-func-ptr.ll b/llvm/test/CodeGen/SBF/BTF/func-func-ptr.ll new file mode 100644 index 00000000000000..a8fa3a5361eef5 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/func-func-ptr.ll @@ -0,0 +1,129 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; void (*a1)(int p1); +; struct t1 { void (*a1)(int p1); } b1; +; void f1(int p2) { } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t1 = type { void (i32)* } + +@a1 = common dso_local local_unnamed_addr global void (i32)* null, align 8, !dbg !0 +@b1 = common dso_local local_unnamed_addr global %struct.t1 zeroinitializer, align 8, !dbg !6 + +; Function Attrs: nounwind readnone +define dso_local void @f1(i32 %p2) local_unnamed_addr #0 !dbg !19 { +entry: + call void @llvm.dbg.value(metadata i32 %p2, metadata !21, metadata !DIExpression()), !dbg !22 + ret void, !dbg !23 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 104 +; CHECK-NEXT: .long 104 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 2) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 8 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 5) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 26 # BTF_KIND_STRUCT(id = 6) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 29 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "p2" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "f1" # string offset=8 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=11 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/t.c" # string offset=17 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "t1" # string offset=26 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "a1" # string offset=29 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 8 # FuncInfo +; CHECK-NEXT: .long 11 # FuncInfo section string offset=11 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 16 # LineInfo +; CHECK-NEXT: .long 11 # LineInfo section string offset=11 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 17 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3091 # Line 3 Col 19 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!15, !16, !17} +!llvm.ident = !{!18} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a1", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/tmp") +!4 = !{} +!5 = !{!0, !6} +!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) +!7 = distinct !DIGlobalVariable(name: "b1", scope: !2, file: !3, line: 2, type: !8, isLocal: false, isDefinition: true) +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 2, size: 64, elements: !9) +!9 = !{!10} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !8, file: !3, line: 2, baseType: !11, size: 64) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = !DISubroutineType(types: !13) +!13 = !{null, !14} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !{i32 2, !"Dwarf Version", i32 4} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{i32 1, !"wchar_size", i32 4} +!18 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} +!19 = distinct !DISubprogram(name: "f1", scope: !3, file: !3, line: 3, type: !12, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !20) +!20 = !{!21} +!21 = !DILocalVariable(name: "p2", arg: 1, scope: !19, file: !3, line: 3, type: !14) +!22 = !DILocation(line: 3, column: 13, scope: !19) +!23 = !DILocation(line: 3, column: 19, scope: !19) diff --git a/llvm/test/CodeGen/SBF/BTF/func-non-void.ll b/llvm/test/CodeGen/SBF/BTF/func-non-void.ll new file mode 100644 index 00000000000000..331a7ab99b65a2 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/func-non-void.ll @@ -0,0 +1,98 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int f1(int a1) { return a1; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +; Function Attrs: nounwind readnone +define dso_local i32 @f1(i32 returned) local_unnamed_addr #0 !dbg !7 { + call void @llvm.dbg.value(metadata i32 %0, metadata !12, metadata !DIExpression()), !dbg !13 + ret i32 %0, !dbg !14 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 2) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 8 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "a1" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "f1" # string offset=8 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=11 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/DNE/t.c" # string offset=17 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 44 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 8 # FuncInfo +; CHECK-NEXT: .long 11 # FuncInfo section string offset=11 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 16 # LineInfo +; CHECK-NEXT: .long 11 # LineInfo section string offset=11 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 17 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1024 # Line 1 Col 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 17 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1042 # Line 1 Col 18 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 345562) (llvm/trunk 345560)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/DNE") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.0 (trunk 345562) (llvm/trunk 345560)"} +!7 = distinct !DISubprogram(name: "f1", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DILocalVariable(name: "a1", arg: 1, scope: !7, file: !1, line: 1, type: !10) +!13 = !DILocation(line: 1, column: 12, scope: !7) +!14 = !DILocation(line: 1, column: 18, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/func-source.ll b/llvm/test/CodeGen/SBF/BTF/func-source.ll new file mode 100644 index 00000000000000..f4dc37a52f481c --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/func-source.ll @@ -0,0 +1,81 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; void f(void) { } +; Compilation flag: +; clang -target bpf -O2 -g -gdwarf-5 -gembed-source -S -emit-llvm t.c +; +; This test embeds the source code in the IR, so the line info should have +; correct reference to the lines in the string table. + +; Function Attrs: norecurse nounwind readnone +define dso_local void @f() local_unnamed_addr #0 !dbg !7 { +entry: + ret void, !dbg !10 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 35 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .byte 102 # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=3 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/t.c" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "void f(void) { }" # string offset=18 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 8 # FuncInfo +; CHECK-NEXT: .long 3 # FuncInfo section string offset=3 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16 # LineInfo +; CHECK-NEXT: .long 3 # LineInfo section string offset=3 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 18 +; CHECK-NEXT: .long 1040 # Line 1 Col 16 + +attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "978599fafe3a080b456e3d95a3710359", source: "void f(void) { }\0A") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 5} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} +!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, isOptimized: true, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !DILocation(line: 1, column: 16, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/func-typedef.ll b/llvm/test/CodeGen/SBF/BTF/func-typedef.ll new file mode 100644 index 00000000000000..dfc8e5bd6a6389 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/func-typedef.ll @@ -0,0 +1,114 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; typedef int _int; +; typedef _int __int; +; __int f(__int a) { return a; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +; Function Attrs: nounwind readnone +define dso_local i32 @f(i32 returned %a) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 %a, metadata !14, metadata !DIExpression()), !dbg !15 + ret i32 %a, !dbg !16 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 35 +; CHECK-NEXT: .long 1 # BTF_KIND_TYPEDEF(id = 1) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 7 # BTF_KIND_TYPEDEF(id = 2) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 12 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 4) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 18 # BTF_KIND_FUNC(id = 5) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "__int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "_int" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=12 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 102 # string offset=18 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=20 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/t.c" # string offset=26 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 44 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 8 # FuncInfo +; CHECK-NEXT: .long 20 # FuncInfo section string offset=20 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 16 # LineInfo +; CHECK-NEXT: .long 20 # LineInfo section string offset=20 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3072 # Line 3 Col 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3092 # Line 3 Col 20 + + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} +!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !13) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !10} +!10 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 2, baseType: !11) +!11 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !1, line: 1, baseType: !12) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !{!14} +!14 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10) +!15 = !DILocation(line: 3, column: 15, scope: !7) +!16 = !DILocation(line: 3, column: 20, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/func-unused-arg.ll b/llvm/test/CodeGen/SBF/BTF/func-unused-arg.ll new file mode 100644 index 00000000000000..ff071582810a8c --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/func-unused-arg.ll @@ -0,0 +1,94 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int f1(int a1) { return 0; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +; Function Attrs: nounwind readnone +define dso_local i32 @f1(i32) local_unnamed_addr #0 !dbg !7 { + call void @llvm.dbg.value(metadata i32 %0, metadata !12, metadata !DIExpression()), !dbg !13 + ret i32 0, !dbg !14 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 2) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 8 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "a1" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "f1" # string offset=8 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=11 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/DNE/t.c" # string offset=17 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 8 # FuncInfo +; CHECK-NEXT: .long 11 # FuncInfo section string offset=11 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 16 # LineInfo +; CHECK-NEXT: .long 11 # LineInfo section string offset=11 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 17 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1042 # Line 1 Col 18 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 345562) (llvm/trunk 345560)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/DNE") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.0 (trunk 345562) (llvm/trunk 345560)"} +!7 = distinct !DISubprogram(name: "f1", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DILocalVariable(name: "a1", arg: 1, scope: !7, file: !1, line: 1, type: !10) +!13 = !DILocation(line: 1, column: 12, scope: !7) +!14 = !DILocation(line: 1, column: 18, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/func-void.ll b/llvm/test/CodeGen/SBF/BTF/func-void.ll new file mode 100644 index 00000000000000..460103383f471d --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/func-void.ll @@ -0,0 +1,75 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; void f1(void) {} +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +; Function Attrs: norecurse nounwind readnone +define dso_local void @f1() local_unnamed_addr #0 !dbg !7 { + ret void, !dbg !10 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 19 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "f1" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=4 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/DNE/t.c" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 8 # FuncInfo +; CHECK-NEXT: .long 4 # FuncInfo section string offset=4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16 # LineInfo +; CHECK-NEXT: .long 4 # LineInfo section string offset=4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1040 # Line 1 Col 16 + +attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 345562) (llvm/trunk 345560)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/DNE") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.0 (trunk 345562) (llvm/trunk 345560)"} +!7 = distinct !DISubprogram(name: "f1", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !DILocation(line: 1, column: 16, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/fwd-no-define.ll b/llvm/test/CodeGen/SBF/BTF/fwd-no-define.ll new file mode 100644 index 00000000000000..1353abed37567c --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/fwd-no-define.ll @@ -0,0 +1,61 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct t1; +; struct t2 {struct t1 *p;} a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t2 = type { %struct.t1* } +%struct.t1 = type opaque + +@a = common dso_local local_unnamed_addr global %struct.t2 zeroinitializer, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 6 # BTF_KIND_FWD(id = 3) +; CHECK-NEXT: .long 117440512 # 0x7000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "t2" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 112 # string offset=4 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "t1" # string offset=6 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", file: !3, line: 2, size: 64, elements: !7) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "p", scope: !6, file: !3, line: 2, baseType: !9, size: 64) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 1, flags: DIFlagFwdDecl) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/fwd-with-define.ll b/llvm/test/CodeGen/SBF/BTF/fwd-with-define.ll new file mode 100644 index 00000000000000..1b39475b2e688c --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/fwd-with-define.ll @@ -0,0 +1,54 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct t1; +; struct t1 {struct t1 *p;} a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t1 = type { %struct.t1* } + +@a = common dso_local local_unnamed_addr global %struct.t1 zeroinitializer, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "t1" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 112 # string offset=4 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 2, size: 64, elements: !7) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "p", scope: !6, file: !3, line: 2, baseType: !9, size: 64) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/global-var-inited.ll b/llvm/test/CodeGen/SBF/BTF/global-var-inited.ll new file mode 100644 index 00000000000000..7766f2676002e5 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/global-var-inited.ll @@ -0,0 +1,55 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int a = 3; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@a = dso_local local_unnamed_addr global i32 3, align 4, !dbg !0 + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 13 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_VAR(id = 2) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 7 # BTF_KIND_DATASEC(id = 3) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long a +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".data" # string offset=7 +; CHECK-NEXT: .byte 0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.20181009 "} diff --git a/llvm/test/CodeGen/SBF/BTF/global-var-sec-readonly.ll b/llvm/test/CodeGen/SBF/BTF/global-var-sec-readonly.ll new file mode 100644 index 00000000000000..a5c41c2a525b58 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/global-var-sec-readonly.ll @@ -0,0 +1,72 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; const int gv1 __attribute__((section("maps"))); +; const int gv2 __attribute__((section("maps"))) = 5; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@gv2 = dso_local local_unnamed_addr constant i32 5, section "maps", align 4, !dbg !0 +@gv1 = dso_local local_unnamed_addr constant i32 0, section "maps", align 4, !dbg !6 + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 96 +; CHECK-NEXT: .long 96 +; CHECK-NEXT: .long 18 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 1) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_VAR(id = 3) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 9 # BTF_KIND_VAR(id = 4) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 13 # BTF_KIND_DATASEC(id = 5) +; CHECK-NEXT: .long 251658242 # 0xf000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long gv2 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long gv1 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "gv2" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "gv1" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "maps" # string offset=13 +; CHECK-NEXT: .byte 0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "gv2", scope: !2, file: !3, line: 2, type: !8, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!4 = !{} +!5 = !{!0, !6} +!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) +!7 = distinct !DIGlobalVariable(name: "gv1", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true) +!8 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !9) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.20181009 "} diff --git a/llvm/test/CodeGen/SBF/BTF/global-var-sec.ll b/llvm/test/CodeGen/SBF/BTF/global-var-sec.ll new file mode 100644 index 00000000000000..8e90d3b70a858d --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/global-var-sec.ll @@ -0,0 +1,68 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int gv1 __attribute__((section("maps"))); +; int gv2 __attribute__((section("maps"))) = 5; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@gv2 = dso_local local_unnamed_addr global i32 5, section "maps", align 4, !dbg !0 +@gv1 = dso_local local_unnamed_addr global i32 0, section "maps", align 4, !dbg !6 + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 84 +; CHECK-NEXT: .long 84 +; CHECK-NEXT: .long 18 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_VAR(id = 2) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 9 # BTF_KIND_VAR(id = 3) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 13 # BTF_KIND_DATASEC(id = 4) +; CHECK-NEXT: .long 251658242 # 0xf000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long gv2 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long gv1 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "gv2" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "gv1" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "maps" # string offset=13 +; CHECK-NEXT: .byte 0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "gv2", scope: !2, file: !3, line: 2, type: !8, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!4 = !{} +!5 = !{!0, !6} +!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) +!7 = distinct !DIGlobalVariable(name: "gv1", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true) +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 8.0.20181009 "} diff --git a/llvm/test/CodeGen/SBF/BTF/int.ll b/llvm/test/CodeGen/SBF/BTF/int.ll new file mode 100644 index 00000000000000..da97c306822728 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/int.ll @@ -0,0 +1,41 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32 0, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/local-var-readonly-1.ll b/llvm/test/CodeGen/SBF/BTF/local-var-readonly-1.ll new file mode 100644 index 00000000000000..ff4aa9e2981578 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/local-var-readonly-1.ll @@ -0,0 +1,104 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; void foo(const void *); +; int test() { +; const char *str = "abcd"; +; const struct { +; unsigned a[4]; +; } val = { .a = {2, 3, 4, 5} }; +; foo(str); +; foo(&val); +; return 0; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.anon = type { [4 x i32] } + +@.str = private unnamed_addr constant [5 x i8] c"abcd\00", align 1 +@__const.test.val = private unnamed_addr constant %struct.anon { [4 x i32] [i32 2, i32 3, i32 4, i32 5] }, align 4 + +; Function Attrs: nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !7 { +entry: + %val = alloca %struct.anon, align 4 + call void @llvm.dbg.value(metadata i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), metadata !12, metadata !DIExpression()), !dbg !25 + %0 = bitcast %struct.anon* %val to i8*, !dbg !26 + call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %0) #4, !dbg !26 + call void @llvm.dbg.declare(metadata %struct.anon* %val, metadata !16, metadata !DIExpression()), !dbg !27 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(16) %0, i8* nonnull align 4 dereferenceable(16) bitcast (%struct.anon* @__const.test.val to i8*), i64 16, i1 false), !dbg !27 + tail call void @foo(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0)) #4, !dbg !28 + call void @foo(i8* nonnull %0) #4, !dbg !29 + call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %0) #4, !dbg !30 + ret i32 0, !dbg !31 +} + +; the initial value of "str" is stored in section .rodata.str1.1 +; the initial value of "val" is stored in section .rodata.cst16 +; CHECK-NOT: BTF_KIND_DATASEC + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #1 + +declare !dbg !32 dso_local void @foo(i8*) local_unnamed_addr #3 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind willreturn } +attributes #2 = { nounwind readnone speculatable willreturn } +attributes #3 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 1e92cffe18a07c12042b57504dfa7fb709b833c8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/tmp") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 1e92cffe18a07c12042b57504dfa7fb709b833c8)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12, !16} +!12 = !DILocalVariable(name: "str", scope: !7, file: !1, line: 3, type: !13) +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!14 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !15) +!15 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!16 = !DILocalVariable(name: "val", scope: !7, file: !1, line: 6, type: !17) +!17 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !18) +!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !7, file: !1, line: 4, size: 128, elements: !19) +!19 = !{!20} +!20 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !18, file: !1, line: 5, baseType: !21, size: 128) +!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 128, elements: !23) +!22 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!23 = !{!24} +!24 = !DISubrange(count: 4) +!25 = !DILocation(line: 0, scope: !7) +!26 = !DILocation(line: 4, column: 3, scope: !7) +!27 = !DILocation(line: 6, column: 5, scope: !7) +!28 = !DILocation(line: 7, column: 3, scope: !7) +!29 = !DILocation(line: 8, column: 3, scope: !7) +!30 = !DILocation(line: 10, column: 1, scope: !7) +!31 = !DILocation(line: 9, column: 3, scope: !7) +!32 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !33, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!33 = !DISubroutineType(types: !34) +!34 = !{null, !35} +!35 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !36, size: 64) +!36 = !DIDerivedType(tag: DW_TAG_const_type, baseType: null) diff --git a/llvm/test/CodeGen/SBF/BTF/local-var-readonly-2.ll b/llvm/test/CodeGen/SBF/BTF/local-var-readonly-2.ll new file mode 100644 index 00000000000000..ebccb3e7718b32 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/local-var-readonly-2.ll @@ -0,0 +1,96 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; void foo(const void *); +; int test() { +; const struct { +; unsigned a[4]; +; char b; +; } val = { .a = {2, 3, 4, 5}, .b = 4 }; +; foo(&val); +; return 0; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.anon = type { [4 x i32], i8 } + +@__const.test.val = private unnamed_addr constant %struct.anon { [4 x i32] [i32 2, i32 3, i32 4, i32 5], i8 4 }, align 4 + +; Function Attrs: nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !7 { +entry: + %val = alloca %struct.anon, align 4 + %0 = bitcast %struct.anon* %val to i8*, !dbg !23 + call void @llvm.lifetime.start.p0i8(i64 20, i8* nonnull %0) #4, !dbg !23 + call void @llvm.dbg.declare(metadata %struct.anon* %val, metadata !12, metadata !DIExpression()), !dbg !24 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(20) %0, i8* nonnull align 4 dereferenceable(20) bitcast (%struct.anon* @__const.test.val to i8*), i64 20, i1 false), !dbg !24 + call void @foo(i8* nonnull %0) #4, !dbg !25 + call void @llvm.lifetime.end.p0i8(i64 20, i8* nonnull %0) #4, !dbg !26 + ret i32 0, !dbg !27 +} + +; the init value of local variable "val" is stored in .rodata section +; CHECK: .long 42 # BTF_KIND_DATASEC +; CHECK-NEXT: .long 251658240 # 0xf000000 +; CHECK-NEXT: .long 0 + +; CHECK: .ascii ".rodata" # string offset=42 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #1 + +declare !dbg !28 dso_local void @foo(i8*) local_unnamed_addr #3 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind willreturn } +attributes #2 = { nounwind readnone speculatable willreturn } +attributes #3 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 1e92cffe18a07c12042b57504dfa7fb709b833c8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/tmp") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 1e92cffe18a07c12042b57504dfa7fb709b833c8)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DILocalVariable(name: "val", scope: !7, file: !1, line: 6, type: !13) +!13 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !14) +!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !7, file: !1, line: 3, size: 160, elements: !15) +!15 = !{!16, !21} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !14, file: !1, line: 4, baseType: !17, size: 128) +!17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !18, size: 128, elements: !19) +!18 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!19 = !{!20} +!20 = !DISubrange(count: 4) +!21 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !14, file: !1, line: 5, baseType: !22, size: 8, offset: 128) +!22 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!23 = !DILocation(line: 3, column: 3, scope: !7) +!24 = !DILocation(line: 6, column: 5, scope: !7) +!25 = !DILocation(line: 7, column: 3, scope: !7) +!26 = !DILocation(line: 9, column: 1, scope: !7) +!27 = !DILocation(line: 8, column: 3, scope: !7) +!28 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !29, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!29 = !DISubroutineType(types: !30) +!30 = !{null, !31} +!31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !32, size: 64) +!32 = !DIDerivedType(tag: DW_TAG_const_type, baseType: null) diff --git a/llvm/test/CodeGen/SBF/BTF/local-var.ll b/llvm/test/CodeGen/SBF/BTF/local-var.ll new file mode 100644 index 00000000000000..a16469638fb2af --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/local-var.ll @@ -0,0 +1,107 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int foo(char a) { volatile short b = 0; return b; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +; Function Attrs: nounwind +define dso_local i32 @foo(i8 signext) local_unnamed_addr #0 !dbg !7 { + %2 = alloca i16, align 2 + call void @llvm.dbg.value(metadata i8 %0, metadata !13, metadata !DIExpression()), !dbg !17 + %3 = bitcast i16* %2 to i8*, !dbg !18 + call void @llvm.lifetime.start.p0i8(i64 2, i8* nonnull %3), !dbg !18 + call void @llvm.dbg.declare(metadata i16* %2, metadata !14, metadata !DIExpression()), !dbg !19 + store volatile i16 0, i16* %2, align 2, !dbg !19, !tbaa !20 + %4 = load volatile i16, i16* %2, align 2, !dbg !24, !tbaa !20 + %5 = sext i16 %4 to i32, !dbg !24 + call void @llvm.lifetime.end.p0i8(i64 2, i8* nonnull %3), !dbg !25 + ret i32 %5, !dbg !26 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 59 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 2) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 8 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 12 # BTF_KIND_FUNC(id = 4) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "char" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=6 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=8 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo" # string offset=12 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/home/yhs/work/tests/llvm/bug/test.c" # string offset=22 +; CHECK-NEXT: .byte 0 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #2 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } +attributes #2 = { argmemonly nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.20181009 "} +!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !12) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!12 = !{!13, !14} +!13 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 1, type: !11) +!14 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 1, type: !15) +!15 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !16) +!16 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) +!17 = !DILocation(line: 1, column: 14, scope: !7) +!18 = !DILocation(line: 1, column: 19, scope: !7) +!19 = !DILocation(line: 1, column: 34, scope: !7) +!20 = !{!21, !21, i64 0} +!21 = !{!"short", !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 1, column: 49, scope: !7) +!25 = !DILocation(line: 1, column: 52, scope: !7) +!26 = !DILocation(line: 1, column: 42, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/longlong.ll b/llvm/test/CodeGen/SBF/BTF/longlong.ll new file mode 100644 index 00000000000000..334b8bae53e60f --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/longlong.ll @@ -0,0 +1,41 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; long long a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i64 0, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 15 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 16777280 # 0x1000040 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "long long int" # string offset=1 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "long long int", size: 64, encoding: DW_ATE_signed) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/map-def-2.ll b/llvm/test/CodeGen/SBF/BTF/map-def-2.ll new file mode 100644 index 00000000000000..487a4ef1c003cd --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/map-def-2.ll @@ -0,0 +1,89 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; struct key_type { +; int a1; +; }; +; typedef struct map_type { +; struct key_type *key; +; } _map_type; +; typedef _map_type __map_type; +; __map_type __attribute__((section(".maps"))) hash_map; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t2.c + +%struct.map_type = type { %struct.key_type* } +%struct.key_type = type { i32 } + +@hash_map = dso_local local_unnamed_addr global %struct.map_type zeroinitializer, section ".maps", align 8, !dbg !0 + +; CHECK: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 2) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 13 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 17 # BTF_KIND_TYPEDEF(id = 4) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 28 # BTF_KIND_TYPEDEF(id = 5) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 38 # BTF_KIND_STRUCT(id = 6) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 47 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 51 # BTF_KIND_VAR(id = 7) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 60 # BTF_KIND_DATASEC(id = 8) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long hash_map +; CHECK-NEXT: .long 8 + +; CHECK: .ascii "key_type" # string offset=1 +; CHECK: .ascii "a1" # string offset=10 +; CHECK: .ascii "int" # string offset=13 +; CHECK: .ascii "__map_type" # string offset=17 +; CHECK: .ascii "_map_type" # string offset=28 +; CHECK: .ascii "map_type" # string offset=38 +; CHECK: .ascii "key" # string offset=47 +; CHECK: .ascii "hash_map" # string offset=51 +; CHECK: .ascii ".maps" # string offset=60 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!16, !17, !18} +!llvm.ident = !{!19} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "hash_map", scope: !2, file: !3, line: 8, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git b8409c03ed90807f3d49c7d98dceea98cf461f7a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "t2.c", directory: "/tmp/home/yhs/tmp1") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "__map_type", file: !3, line: 7, baseType: !7) +!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "_map_type", file: !3, line: 6, baseType: !8) +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_type", file: !3, line: 4, size: 64, elements: !9) +!9 = !{!10} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "key", scope: !8, file: !3, line: 5, baseType: !11, size: 64) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "key_type", file: !3, line: 1, size: 32, elements: !13) +!13 = !{!14} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !12, file: !3, line: 2, baseType: !15, size: 32) +!15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!16 = !{i32 7, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{i32 1, !"wchar_size", i32 4} +!19 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git b8409c03ed90807f3d49c7d98dceea98cf461f7a)"} diff --git a/llvm/test/CodeGen/SBF/BTF/map-def-3.ll b/llvm/test/CodeGen/SBF/BTF/map-def-3.ll new file mode 100644 index 00000000000000..674a8b91fd38a9 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/map-def-3.ll @@ -0,0 +1,64 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; struct key_type { +; int a1; +; }; +; const struct key_type __attribute__((section(".maps"))) hash_map; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t3.c + +%struct.key_type = type { i32 } + +@hash_map = dso_local local_unnamed_addr constant %struct.key_type zeroinitializer, section ".maps", align 4, !dbg !0 + +; CHECK: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 2) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 5 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 14 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 17 # BTF_KIND_VAR(id = 4) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 26 # BTF_KIND_DATASEC(id = 5) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long hash_map +; CHECK-NEXT: .long 4 + +; CHECK: .ascii "int" # string offset=1 +; CHECK: .ascii "key_type" # string offset=5 +; CHECK: .ascii "a1" # string offset=14 +; CHECK: .ascii "hash_map" # string offset=17 +; CHECK: .ascii ".maps" # string offset=26 + + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "hash_map", scope: !2, file: !3, line: 4, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 5bd074629f00d4798674b411cf00216f38016483)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "t3.c", directory: "/tmp/home/yhs/tmp1") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !7) +!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "key_type", file: !3, line: 1, size: 32, elements: !8) +!8 = !{!9} +!9 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !7, file: !3, line: 2, baseType: !10, size: 32) +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{i32 7, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 5bd074629f00d4798674b411cf00216f38016483)"} diff --git a/llvm/test/CodeGen/SBF/BTF/map-def.ll b/llvm/test/CodeGen/SBF/BTF/map-def.ll new file mode 100644 index 00000000000000..1d6514c0999fe5 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/map-def.ll @@ -0,0 +1,119 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct key_type { +; int a; +; int b; +; }; +; struct map_type { +; struct key_type *key; +; unsigned *value; +; }; +; struct map_type __attribute__((section(".maps"))) hash_map; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.map_type = type { %struct.key_type*, i32* } +%struct.key_type = type { i32, i32 } + +@hash_map = dso_local local_unnamed_addr global %struct.map_type zeroinitializer, section ".maps", align 8, !dbg !0 + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 168 +; CHECK-NEXT: .long 168 +; CHECK-NEXT: .long 65 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 2) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 14 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 18 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 31 # BTF_KIND_STRUCT(id = 6) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 44 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 64 # 0x40 +; CHECK-NEXT: .long 50 # BTF_KIND_VAR(id = 7) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 59 # BTF_KIND_DATASEC(id = 8) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long hash_map +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "key_type" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 98 # string offset=12 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=14 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "unsigned int" # string offset=18 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "map_type" # string offset=31 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "key" # string offset=40 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "value" # string offset=44 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "hash_map" # string offset=50 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".maps" # string offset=59 +; CHECK-NEXT: .byte 0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!18, !19, !20} +!llvm.ident = !{!21} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "hash_map", scope: !2, file: !3, line: 9, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 9.0.0 (trunk 364157) (llvm/trunk 364156)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/llvm") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_type", file: !3, line: 5, size: 128, elements: !7) +!7 = !{!8, !15} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "key", scope: !6, file: !3, line: 6, baseType: !9, size: 64) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "key_type", file: !3, line: 1, size: 64, elements: !11) +!11 = !{!12, !14} +!12 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !10, file: !3, line: 2, baseType: !13, size: 32) +!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!14 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !10, file: !3, line: 3, baseType: !13, size: 32, offset: 32) +!15 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !6, file: !3, line: 7, baseType: !16, size: 64, offset: 64) +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64) +!17 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!18 = !{i32 2, !"Dwarf Version", i32 4} +!19 = !{i32 2, !"Debug Info Version", i32 3} +!20 = !{i32 1, !"wchar_size", i32 4} +!21 = !{!"clang version 9.0.0 (trunk 364157) (llvm/trunk 364156)"} diff --git a/llvm/test/CodeGen/SBF/BTF/pruning-const.ll b/llvm/test/CodeGen/SBF/BTF/pruning-const.ll new file mode 100644 index 00000000000000..7ebe980bdd7ddd --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/pruning-const.ll @@ -0,0 +1,119 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; Source: +; struct tt; +; struct s1 { const struct tt *mp; }; +; int test1(struct s1 *arg) +; { +; return 0; +; } +; +; struct tt { int m1; int m2; }; +; struct s2 { const struct tt m3; }; +; int test2(struct s2 *arg) +; { +; return arg->m3.m1; +; } +; Compilation flags: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.s1 = type { %struct.tt* } +%struct.tt = type { i32, i32 } +%struct.s2 = type { %struct.tt } + +; Function Attrs: norecurse nounwind readnone +define dso_local i32 @test1(%struct.s1* nocapture readnone %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.s1* %arg, metadata !22, metadata !DIExpression()), !dbg !23 + ret i32 0, !dbg !24 +} + +; Function Attrs: norecurse nounwind readonly +define dso_local i32 @test2(%struct.s2* nocapture readonly %arg) local_unnamed_addr #1 !dbg !25 { +entry: + call void @llvm.dbg.value(metadata %struct.s2* %arg, metadata !33, metadata !DIExpression()), !dbg !34 + %m1 = getelementptr inbounds %struct.s2, %struct.s2* %arg, i64 0, i32 0, i32 0, !dbg !35 + %0 = load i32, i32* %m1, align 4, !dbg !35, !tbaa !36 + ret i32 %0, !dbg !42 +} + +; CHECK: .long 0 # BTF_KIND_CONST(id = 4) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 10 + +; CHECK: .long 60 # BTF_KIND_STRUCT(id = 9) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 63 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 + +; CHECK: .long 66 # BTF_KIND_STRUCT(id = 10) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 69 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 32 # 0x20 + +; CHECK: .ascii "s2" # string offset=60 +; CHECK: .ascii "m3" # string offset=63 +; CHECK: .ascii "tt" # string offset=66 +; CHECK: .ascii "m1" # string offset=69 +; CHECK: .ascii "m2" # string offset=72 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 7cfd267c518aba226b34b7fbfe8db70000b22053)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/btf") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 7cfd267c518aba226b34b7fbfe8db70000b22053)"} +!7 = distinct !DISubprogram(name: "test1", scope: !1, file: !1, line: 3, type: !8, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !21) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 2, size: 64, elements: !13) +!13 = !{!14} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "mp", scope: !12, file: !1, line: 2, baseType: !15, size: 64) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !17) +!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "tt", file: !1, line: 8, size: 64, elements: !18) +!18 = !{!19, !20} +!19 = !DIDerivedType(tag: DW_TAG_member, name: "m1", scope: !17, file: !1, line: 8, baseType: !10, size: 32) +!20 = !DIDerivedType(tag: DW_TAG_member, name: "m2", scope: !17, file: !1, line: 8, baseType: !10, size: 32, offset: 32) +!21 = !{!22} +!22 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 3, type: !11) +!23 = !DILocation(line: 0, scope: !7) +!24 = !DILocation(line: 5, column: 3, scope: !7) +!25 = distinct !DISubprogram(name: "test2", scope: !1, file: !1, line: 10, type: !26, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !32) +!26 = !DISubroutineType(types: !27) +!27 = !{!10, !28} +!28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !29, size: 64) +!29 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s2", file: !1, line: 9, size: 64, elements: !30) +!30 = !{!31} +!31 = !DIDerivedType(tag: DW_TAG_member, name: "m3", scope: !29, file: !1, line: 9, baseType: !16, size: 64) +!32 = !{!33} +!33 = !DILocalVariable(name: "arg", arg: 1, scope: !25, file: !1, line: 10, type: !28) +!34 = !DILocation(line: 0, scope: !25) +!35 = !DILocation(line: 12, column: 18, scope: !25) +!36 = !{!37, !39, i64 0} +!37 = !{!"s2", !38, i64 0} +!38 = !{!"tt", !39, i64 0, !39, i64 4} +!39 = !{!"int", !40, i64 0} +!40 = !{!"omnipotent char", !41, i64 0} +!41 = !{!"Simple C/C++ TBAA"} +!42 = !DILocation(line: 12, column: 3, scope: !25) diff --git a/llvm/test/CodeGen/SBF/BTF/pruning-multi-derived-type.ll b/llvm/test/CodeGen/SBF/BTF/pruning-multi-derived-type.ll new file mode 100644 index 00000000000000..1011341a70610c --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/pruning-multi-derived-type.ll @@ -0,0 +1,86 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; Source: +; struct t1 { +; int a; +; }; +; struct t2 { +; const struct t1 * const a; +; }; +; int foo(struct t2 *arg) { return 0; } +; int bar(const struct t1 * const arg) { return 0; } +; Compilation flags: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t2 = type { %struct.t1* } +%struct.t1 = type { i32 } + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define dso_local i32 @foo(%struct.t2* nocapture noundef readnone %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.t2* %arg, metadata !22, metadata !DIExpression()), !dbg !23 + ret i32 0, !dbg !24 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define dso_local i32 @bar(%struct.t1* nocapture noundef readnone %arg) local_unnamed_addr #0 !dbg !25 { +entry: + call void @llvm.dbg.value(metadata %struct.t1* %arg, metadata !29, metadata !DIExpression()), !dbg !30 + ret i32 0, !dbg !31 +} + +; CHECK: .long 10 # BTF_KIND_INT(id = 7) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 + +; CHECK: .long 69 # BTF_KIND_STRUCT(id = 9) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 7 + +; CHECK: .byte 97 # string offset=4 +; CHECK: .ascii "t1" # string offset=69 + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willreturn "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git c34c8afcb85ae9142d0f783bb899c464e8bd2356)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_ptr", checksumkind: CSK_MD5, checksum: "d43a0541e830263021772349589e47a5") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 7, !"frame-pointer", i32 2} +!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git c34c8afcb85ae9142d0f783bb899c464e8bd2356)"} +!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 7, type: !8, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !21) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", file: !1, line: 4, size: 64, elements: !13) +!13 = !{!14} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !12, file: !1, line: 5, baseType: !15, size: 64) +!15 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !16) +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64) +!17 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !18) +!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !1, line: 1, size: 32, elements: !19) +!19 = !{!20} +!20 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !18, file: !1, line: 2, baseType: !10, size: 32) +!21 = !{!22} +!22 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 7, type: !11) +!23 = !DILocation(line: 0, scope: !7) +!24 = !DILocation(line: 7, column: 27, scope: !7) +!25 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 8, type: !26, scopeLine: 8, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !28) +!26 = !DISubroutineType(types: !27) +!27 = !{!10, !15} +!28 = !{!29} +!29 = !DILocalVariable(name: "arg", arg: 1, scope: !25, file: !1, line: 8, type: !15) +!30 = !DILocation(line: 0, scope: !25) +!31 = !DILocation(line: 8, column: 40, scope: !25) diff --git a/llvm/test/CodeGen/SBF/BTF/pruning-typedef.ll b/llvm/test/CodeGen/SBF/BTF/pruning-typedef.ll new file mode 100644 index 00000000000000..5dd38e6bbeed31 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/pruning-typedef.ll @@ -0,0 +1,127 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; Source: +; struct tt; +; typedef struct tt _tt; +; typedef _tt __tt; +; struct s1 { __tt *mp; }; +; int test1(struct s1 *arg) +; { +; return 0; +; } +; +; struct tt { int m1; int m2; }; +; struct s2 { __tt m3; }; +; int test2(struct s2 *arg) +; { +; return arg->m3.m1; +; } +; Compilation flags: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.s1 = type { %struct.tt* } +%struct.tt = type { i32, i32 } +%struct.s2 = type { %struct.tt } + +; Function Attrs: norecurse nounwind readnone +define dso_local i32 @test1(%struct.s1* nocapture readnone %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.s1* %arg, metadata !23, metadata !DIExpression()), !dbg !24 + ret i32 0, !dbg !25 +} + +; Function Attrs: norecurse nounwind readonly +define dso_local i32 @test2(%struct.s2* nocapture readonly %arg) local_unnamed_addr #1 !dbg !26 { +entry: + call void @llvm.dbg.value(metadata %struct.s2* %arg, metadata !34, metadata !DIExpression()), !dbg !35 + %m1 = getelementptr inbounds %struct.s2, %struct.s2* %arg, i64 0, i32 0, i32 0, !dbg !36 + %0 = load i32, i32* %m1, align 4, !dbg !36, !tbaa !37 + ret i32 %0, !dbg !43 +} + +; CHECK: .long 7 # BTF_KIND_TYPEDEF(id = 4) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 12 # BTF_KIND_TYPEDEF(id = 5) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 11 + +; CHECK: .long 69 # BTF_KIND_STRUCT(id = 10) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 + +; CHECK: .long 75 # BTF_KIND_STRUCT(id = 11) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 78 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 81 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 32 # 0x20 + +; CHECK: .ascii "__tt" # string offset=7 +; CHECK: .ascii "_tt" # string offset=12 +; CHECK: .ascii "s2" # string offset=69 +; CHECK: .ascii "m3" # string offset=72 +; CHECK: .ascii "tt" # string offset=75 +; CHECK: .ascii "m1" # string offset=78 +; CHECK: .ascii "m2" # string offset=81 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 7cfd267c518aba226b34b7fbfe8db70000b22053)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/btf") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 7cfd267c518aba226b34b7fbfe8db70000b22053)"} +!7 = distinct !DISubprogram(name: "test1", scope: !1, file: !1, line: 5, type: !8, scopeLine: 6, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !22) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 4, size: 64, elements: !13) +!13 = !{!14} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "mp", scope: !12, file: !1, line: 4, baseType: !15, size: 64) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = !DIDerivedType(tag: DW_TAG_typedef, name: "__tt", file: !1, line: 3, baseType: !17) +!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "_tt", file: !1, line: 2, baseType: !18) +!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "tt", file: !1, line: 10, size: 64, elements: !19) +!19 = !{!20, !21} +!20 = !DIDerivedType(tag: DW_TAG_member, name: "m1", scope: !18, file: !1, line: 10, baseType: !10, size: 32) +!21 = !DIDerivedType(tag: DW_TAG_member, name: "m2", scope: !18, file: !1, line: 10, baseType: !10, size: 32, offset: 32) +!22 = !{!23} +!23 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 5, type: !11) +!24 = !DILocation(line: 0, scope: !7) +!25 = !DILocation(line: 7, column: 3, scope: !7) +!26 = distinct !DISubprogram(name: "test2", scope: !1, file: !1, line: 12, type: !27, scopeLine: 13, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !33) +!27 = !DISubroutineType(types: !28) +!28 = !{!10, !29} +!29 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !30, size: 64) +!30 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s2", file: !1, line: 11, size: 64, elements: !31) +!31 = !{!32} +!32 = !DIDerivedType(tag: DW_TAG_member, name: "m3", scope: !30, file: !1, line: 11, baseType: !16, size: 64) +!33 = !{!34} +!34 = !DILocalVariable(name: "arg", arg: 1, scope: !26, file: !1, line: 12, type: !29) +!35 = !DILocation(line: 0, scope: !26) +!36 = !DILocation(line: 14, column: 18, scope: !26) +!37 = !{!38, !40, i64 0} +!38 = !{!"s2", !39, i64 0} +!39 = !{!"tt", !40, i64 0, !40, i64 4} +!40 = !{!"int", !41, i64 0} +!41 = !{!"omnipotent char", !42, i64 0} +!42 = !{!"Simple C/C++ TBAA"} +!43 = !DILocation(line: 14, column: 3, scope: !26) diff --git a/llvm/test/CodeGen/SBF/BTF/ptr-const-void.ll b/llvm/test/CodeGen/SBF/BTF/ptr-const-void.ll new file mode 100644 index 00000000000000..50e2a6754a8750 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/ptr-const-void.ll @@ -0,0 +1,42 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; const void *a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@p = common dso_local local_unnamed_addr global i8* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!8, !9, !10} +!llvm.ident = !{!11} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 2) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DIDerivedType(tag: DW_TAG_const_type, baseType: null) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"wchar_size", i32 4} +!11 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/ptr-func-1.ll b/llvm/test/CodeGen/SBF/BTF/ptr-func-1.ll new file mode 100644 index 00000000000000..ecf63ed3890600 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/ptr-func-1.ll @@ -0,0 +1,43 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; void (*a)(void); +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global void ()* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 2) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DISubroutineType(types: !8) +!8 = !{null} +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/ptr-func-2.ll b/llvm/test/CodeGen/SBF/BTF/ptr-func-2.ll new file mode 100644 index 00000000000000..9cbb49dce2dc75 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/ptr-func-2.ll @@ -0,0 +1,61 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int (*a)(int a, char b); +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32 (i32, i8)* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 2) +; CHECK-NEXT: .long 218103810 # 0xd000002 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=5 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !9, !10} +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/ptr-func-3.ll b/llvm/test/CodeGen/SBF/BTF/ptr-func-3.ll new file mode 100644 index 00000000000000..37d78353ee979b --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/ptr-func-3.ll @@ -0,0 +1,61 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; typedef int __int; +; __int (*a)(__int a, __int b); +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32 (i32, i32)* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 68 +; CHECK-NEXT: .long 68 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 2) +; CHECK-NEXT: .long 218103810 # 0xd000002 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_TYPEDEF(id = 3) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 7 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "__int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=7 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !9, !9} +!9 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !3, line: 1, baseType: !10) +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/ptr-int.ll b/llvm/test/CodeGen/SBF/BTF/ptr-int.ll new file mode 100644 index 00000000000000..c2cc70451161a5 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/ptr-int.ll @@ -0,0 +1,45 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int *a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!8, !9, !10} +!llvm.ident = !{!11} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"wchar_size", i32 4} +!11 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/ptr-prune-type.ll b/llvm/test/CodeGen/SBF/BTF/ptr-prune-type.ll new file mode 100644 index 00000000000000..aad49284a76aee --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/ptr-prune-type.ll @@ -0,0 +1,83 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct t { +; int a; +; }; +; struct t2 { +; struct t *f1; +; }; +; struct t2 __attribute__((section("prune_types"))) g; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t2 = type { %struct.t* } +%struct.t = type { i32 } + +@g = dso_local local_unnamed_addr global %struct.t2 zeroinitializer, section "prune_types", align 8, !dbg !0 + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 88 +; CHECK-NEXT: .long 88 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 7 # BTF_KIND_VAR(id = 3) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 9 # BTF_KIND_DATASEC(id = 4) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long g +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 21 # BTF_KIND_FWD(id = 5) +; CHECK-NEXT: .long 117440512 # 0x7000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "t2" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "f1" # string offset=4 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 103 # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "prune_types" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 116 # string offset=21 +; CHECK-NEXT: .byte 0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!14, !15, !16} +!llvm.ident = !{!17} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 7, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 9.0.0 (trunk 364157) (llvm/trunk 364156)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/llvm") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", file: !3, line: 4, size: 64, elements: !7) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "f1", scope: !6, file: !3, line: 5, baseType: !9, size: 64) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !3, line: 1, size: 32, elements: !11) +!11 = !{!12} +!12 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !10, file: !3, line: 2, baseType: !13, size: 32) +!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!14 = !{i32 2, !"Dwarf Version", i32 4} +!15 = !{i32 2, !"Debug Info Version", i32 3} +!16 = !{i32 1, !"wchar_size", i32 4} +!17 = !{!"clang version 9.0.0 (trunk 364157) (llvm/trunk 364156)"} diff --git a/llvm/test/CodeGen/SBF/BTF/ptr-void.ll b/llvm/test/CodeGen/SBF/BTF/ptr-void.ll new file mode 100644 index 00000000000000..557b44cc9c6cb3 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/ptr-void.ll @@ -0,0 +1,38 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; void *a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i8* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} diff --git a/llvm/test/CodeGen/SBF/BTF/ptr-volatile-const-void.ll b/llvm/test/CodeGen/SBF/BTF/ptr-volatile-const-void.ll new file mode 100644 index 00000000000000..881c10669a1e45 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/ptr-volatile-const-void.ll @@ -0,0 +1,46 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; volatile const void *p; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@p = common dso_local local_unnamed_addr global i8* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 2) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 3) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !8) +!8 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: null) +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/ptr-volatile-void.ll b/llvm/test/CodeGen/SBF/BTF/ptr-volatile-void.ll new file mode 100644 index 00000000000000..21cf61309bb769 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/ptr-volatile-void.ll @@ -0,0 +1,42 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; volatile void *a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@p = common dso_local local_unnamed_addr global i8* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!8, !9, !10} +!llvm.ident = !{!11} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 2) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: null) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"wchar_size", i32 4} +!11 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/restrict-ptr.ll b/llvm/test/CodeGen/SBF/BTF/restrict-ptr.ll new file mode 100644 index 00000000000000..c5350f302ca2a9 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/restrict-ptr.ll @@ -0,0 +1,49 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int * restrict p; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@p = common dso_local local_unnamed_addr global i32* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # BTF_KIND_RESTRICT(id = 1) +; CHECK-NEXT: .long 184549376 # 0xb000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !7) +!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64) +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/short.ll b/llvm/test/CodeGen/SBF/BTF/short.ll new file mode 100644 index 00000000000000..302739ce4c89c9 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/short.ll @@ -0,0 +1,42 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; short a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + + +@a = common dso_local local_unnamed_addr global i16 0, align 2, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16777232 # 0x1000010 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "short" # string offset=1 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/static-func.ll b/llvm/test/CodeGen/SBF/BTF/static-func.ll new file mode 100644 index 00000000000000..074b88a807677b --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/static-func.ll @@ -0,0 +1,95 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; extern int foo(void); +; static __attribute__((noinline)) int test1() { return foo(); } +; int test2() { return test1(); } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +; Function Attrs: nounwind +define dso_local i32 @test2() local_unnamed_addr #0 !dbg !12 { +entry: + %call = tail call fastcc i32 @test1(), !dbg !13 + ret i32 %call, !dbg !14 +} +; Function Attrs: noinline nounwind +define internal fastcc i32 @test1() unnamed_addr #1 !dbg !15 { +entry: + %call = tail call i32 @foo() #3, !dbg !16 + ret i32 %call, !dbg !17 +} +declare !dbg !4 dso_local i32 @foo() local_unnamed_addr #2 + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 88 +; CHECK-NEXT: .long 88 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 4) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 54 # BTF_KIND_FUNC(id = 5) +; CHECK-NEXT: .long 201326592 # 0xc000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 6) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 60 # BTF_KIND_FUNC(id = 7) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test2" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=11 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/bugs/test.c" # string offset=17 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test1" # string offset=54 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo" # string offset=60 +; CHECK-NEXT: .byte 0 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { noinline nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9, !10} +!llvm.ident = !{!11} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 000f95c4157aee07bd4ffc3f59ffdb6c7ecae4af)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/bugs") +!2 = !{} +!3 = !{!4} +!4 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7} +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !{i32 7, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"wchar_size", i32 4} +!11 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 000f95c4157aee07bd4ffc3f59ffdb6c7ecae4af)"} +!12 = distinct !DISubprogram(name: "test2", scope: !1, file: !1, line: 3, type: !5, scopeLine: 3, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!13 = !DILocation(line: 3, column: 22, scope: !12) +!14 = !DILocation(line: 3, column: 15, scope: !12) +!15 = distinct !DISubprogram(name: "test1", scope: !1, file: !1, line: 2, type: !5, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!16 = !DILocation(line: 2, column: 55, scope: !15) +!17 = !DILocation(line: 2, column: 48, scope: !15) diff --git a/llvm/test/CodeGen/SBF/BTF/static-var-derived-type.ll b/llvm/test/CodeGen/SBF/BTF/static-var-derived-type.ll new file mode 100644 index 00000000000000..0785d72cfcc0fb --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/static-var-derived-type.ll @@ -0,0 +1,189 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; typedef int * int_ptr; +; static int * volatile v1; +; static const int * volatile v2; +; static volatile int_ptr v3 = 0; +; static volatile const int_ptr v4 = 0; +; long foo() { return (long)(v1 - v2 + v3 - v4); } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@v1 = internal global i32* null, align 8, !dbg !0 +@v2 = internal global i32* null, align 8, !dbg !8 +@v3 = internal global i32* null, align 8, !dbg !14 +@v4 = internal constant i32* null, align 8, !dbg !19 + +; Function Attrs: norecurse nounwind +define dso_local i64 @foo() local_unnamed_addr #0 !dbg !27 { + %1 = load volatile i32*, i32** @v1, align 8, !dbg !29, !tbaa !30 + %2 = load volatile i32*, i32** @v2, align 8, !dbg !34, !tbaa !30 + %3 = ptrtoint i32* %1 to i64, !dbg !35 + %4 = ptrtoint i32* %2 to i64, !dbg !35 + %5 = sub i64 %3, %4, !dbg !35 + %6 = ashr exact i64 %5, 2, !dbg !35 + %7 = load volatile i32*, i32** @v3, align 8, !dbg !36, !tbaa !30 + %8 = getelementptr inbounds i32, i32* %7, i64 %6, !dbg !37 + %9 = load volatile i32*, i32** @v4, align 8, !dbg !38, !tbaa !30 + %10 = ptrtoint i32* %8 to i64, !dbg !39 + %11 = ptrtoint i32* %9 to i64, !dbg !39 + %12 = sub i64 %10, %11, !dbg !39 + %13 = ashr exact i64 %12, 2, !dbg !39 + ret i64 %13, !dbg !40 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 288 +; CHECK-NEXT: .long 288 +; CHECK-NEXT: .long 95 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 16777280 # 0x1000040 +; CHECK-NEXT: .long 10 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 4) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 5) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 58 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 62 # BTF_KIND_VAR(id = 7) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 8) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 9) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 10) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 65 # BTF_KIND_VAR(id = 11) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 12) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 13 +; CHECK-NEXT: .long 68 # BTF_KIND_TYPEDEF(id = 13) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 76 # BTF_KIND_VAR(id = 14) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 15) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 79 # BTF_KIND_VAR(id = 16) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 15 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 82 # BTF_KIND_DATASEC(id = 17) +; CHECK-NEXT: .long 251658243 # 0xf000003 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long v1 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long v2 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 14 +; CHECK-NEXT: .long v3 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 87 # BTF_KIND_DATASEC(id = 18) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long v4 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "long int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=14 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/home/yhs/work/tests/llvm/bugs/test.c" # string offset=20 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=58 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "v1" # string offset=62 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "v2" # string offset=65 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int_ptr" # string offset=68 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "v3" # string offset=76 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "v4" # string offset=79 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".bss" # string offset=82 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".rodata" # string offset=87 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!23, !24, !25} +!llvm.ident = !{!26} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "v1", scope: !2, file: !3, line: 2, type: !22, isLocal: true, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !7, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bugs") +!4 = !{} +!5 = !{!6} +!6 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed) +!7 = !{!0, !8, !14, !19} +!8 = !DIGlobalVariableExpression(var: !9, expr: !DIExpression()) +!9 = distinct !DIGlobalVariable(name: "v2", scope: !2, file: !3, line: 3, type: !10, isLocal: true, isDefinition: true) +!10 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !11) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13) +!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!14 = !DIGlobalVariableExpression(var: !15, expr: !DIExpression()) +!15 = distinct !DIGlobalVariable(name: "v3", scope: !2, file: !3, line: 4, type: !16, isLocal: true, isDefinition: true) +!16 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !17) +!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "int_ptr", file: !3, line: 1, baseType: !18) +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64) +!19 = !DIGlobalVariableExpression(var: !20, expr: !DIExpression()) +!20 = distinct !DIGlobalVariable(name: "v4", scope: !2, file: !3, line: 5, type: !21, isLocal: true, isDefinition: true) +!21 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !16) +!22 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !18) +!23 = !{i32 2, !"Dwarf Version", i32 4} +!24 = !{i32 2, !"Debug Info Version", i32 3} +!25 = !{i32 1, !"wchar_size", i32 4} +!26 = !{!"clang version 8.0.20181009 "} +!27 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 6, type: !28, isLocal: false, isDefinition: true, scopeLine: 6, isOptimized: true, unit: !2, retainedNodes: !4) +!28 = !DISubroutineType(types: !5) +!29 = !DILocation(line: 6, column: 28, scope: !27) +!30 = !{!31, !31, i64 0} +!31 = !{!"any pointer", !32, i64 0} +!32 = !{!"omnipotent char", !33, i64 0} +!33 = !{!"Simple C/C++ TBAA"} +!34 = !DILocation(line: 6, column: 33, scope: !27) +!35 = !DILocation(line: 6, column: 31, scope: !27) +!36 = !DILocation(line: 6, column: 38, scope: !27) +!37 = !DILocation(line: 6, column: 36, scope: !27) +!38 = !DILocation(line: 6, column: 43, scope: !27) +!39 = !DILocation(line: 6, column: 41, scope: !27) +!40 = !DILocation(line: 6, column: 14, scope: !27) diff --git a/llvm/test/CodeGen/SBF/BTF/static-var-inited-sec.ll b/llvm/test/CodeGen/SBF/BTF/static-var-inited-sec.ll new file mode 100644 index 00000000000000..8752af0602039a --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/static-var-inited-sec.ll @@ -0,0 +1,129 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; static volatile char a __attribute__((section("maps"))) = 3; +; int foo() { +; static volatile short b __attribute__((section("maps"))) = 4; +; return a + b; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@foo.b = internal global i16 4, section "maps", align 2, !dbg !0 +@a = internal global i8 3, section "maps", align 1, !dbg !10 + +; Function Attrs: norecurse nounwind +define dso_local i32 @foo() local_unnamed_addr #0 !dbg !2 { + %1 = load volatile i8, i8* @a, align 1, !dbg !20, !tbaa !21 + %2 = sext i8 %1 to i32, !dbg !20 + %3 = load volatile i16, i16* @foo.b, align 2, !dbg !24, !tbaa !25 + %4 = sext i16 %3 to i32, !dbg !24 + %5 = add nsw i32 %4, %2, !dbg !27 + ret i32 %5, !dbg !28 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 164 +; CHECK-NEXT: .long 164 +; CHECK-NEXT: .long 76 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 4) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 52 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16777232 # 0x1000010 +; CHECK-NEXT: .long 58 # BTF_KIND_VAR(id = 6) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 7) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 64 # BTF_KIND_INT(id = 8) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 69 # BTF_KIND_VAR(id = 9) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 71 # BTF_KIND_DATASEC(id = 10) +; CHECK-NEXT: .long 251658242 # 0xf000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long foo.b +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long a +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/home/yhs/work/tests/llvm/bug/test.c" # string offset=15 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "short" # string offset=52 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo.b" # string offset=58 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=64 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=69 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "maps" # string offset=71 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!7} +!llvm.module.flags = !{!16, !17, !18} +!llvm.ident = !{!19} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !14, isLocal: true, isDefinition: true) +!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8) +!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!4 = !DISubroutineType(types: !5) +!5 = !{!6} +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None) +!8 = !{} +!9 = !{!0, !10} +!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression()) +!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true) +!12 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !13) +!13 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!14 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !15) +!15 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{i32 1, !"wchar_size", i32 4} +!19 = !{!"clang version 8.0.20181009 "} +!20 = !DILocation(line: 4, column: 10, scope: !2) +!21 = !{!22, !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 4, column: 14, scope: !2) +!25 = !{!26, !26, i64 0} +!26 = !{!"short", !22, i64 0} +!27 = !DILocation(line: 4, column: 12, scope: !2) +!28 = !DILocation(line: 4, column: 3, scope: !2) diff --git a/llvm/test/CodeGen/SBF/BTF/static-var-inited.ll b/llvm/test/CodeGen/SBF/BTF/static-var-inited.ll new file mode 100644 index 00000000000000..48a527d13d5ca8 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/static-var-inited.ll @@ -0,0 +1,129 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; static volatile char a = 3; +; int foo() { +; static volatile short b = 4; +; return a + b; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@foo.b = internal global i16 4, align 2, !dbg !0 +@a = internal global i8 3, align 1, !dbg !10 + +; Function Attrs: norecurse nounwind +define dso_local i32 @foo() local_unnamed_addr #0 !dbg !2 { + %1 = load volatile i8, i8* @a, align 1, !dbg !20, !tbaa !21 + %2 = sext i8 %1 to i32, !dbg !20 + %3 = load volatile i16, i16* @foo.b, align 2, !dbg !24, !tbaa !25 + %4 = sext i16 %3 to i32, !dbg !24 + %5 = add nsw i32 %4, %2, !dbg !27 + ret i32 %5, !dbg !28 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 164 +; CHECK-NEXT: .long 164 +; CHECK-NEXT: .long 77 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 4) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 52 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16777232 # 0x1000010 +; CHECK-NEXT: .long 58 # BTF_KIND_VAR(id = 6) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 7) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 64 # BTF_KIND_INT(id = 8) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 69 # BTF_KIND_VAR(id = 9) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 71 # BTF_KIND_DATASEC(id = 10) +; CHECK-NEXT: .long 251658242 # 0xf000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long foo.b +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long a +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/home/yhs/work/tests/llvm/bug/test.c" # string offset=15 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "short" # string offset=52 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo.b" # string offset=58 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=64 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=69 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".data" # string offset=71 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!7} +!llvm.module.flags = !{!16, !17, !18} +!llvm.ident = !{!19} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !14, isLocal: true, isDefinition: true) +!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8) +!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!4 = !DISubroutineType(types: !5) +!5 = !{!6} +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None) +!8 = !{} +!9 = !{!0, !10} +!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression()) +!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true) +!12 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !13) +!13 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!14 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !15) +!15 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{i32 1, !"wchar_size", i32 4} +!19 = !{!"clang version 8.0.20181009 "} +!20 = !DILocation(line: 4, column: 10, scope: !2) +!21 = !{!22, !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 4, column: 14, scope: !2) +!25 = !{!26, !26, i64 0} +!26 = !{!"short", !22, i64 0} +!27 = !DILocation(line: 4, column: 12, scope: !2) +!28 = !DILocation(line: 4, column: 3, scope: !2) diff --git a/llvm/test/CodeGen/SBF/BTF/static-var-readonly-sec.ll b/llvm/test/CodeGen/SBF/BTF/static-var-readonly-sec.ll new file mode 100644 index 00000000000000..bbbb3262988dbc --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/static-var-readonly-sec.ll @@ -0,0 +1,137 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; static volatile const char __attribute__((section("maps"))) a; +; int foo() { +; static volatile const short b __attribute__((section("maps"))) = 3; +; return a + b; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@foo.b = internal constant i16 3, section "maps", align 2, !dbg !0 +@a = internal constant i8 0, section "maps", align 1, !dbg !10 + +; Function Attrs: norecurse nounwind +define dso_local i32 @foo() local_unnamed_addr #0 !dbg !2 { + %1 = load volatile i8, i8* @a, align 1, !dbg !22, !tbaa !23 + %2 = sext i8 %1 to i32, !dbg !22 + %3 = load volatile i16, i16* @foo.b, align 2, !dbg !26, !tbaa !27 + %4 = sext i16 %3 to i32, !dbg !26 + %5 = add nsw i32 %4, %2, !dbg !29 + ret i32 %5, !dbg !30 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 188 +; CHECK-NEXT: .long 188 +; CHECK-NEXT: .long 76 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 4) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 5) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 52 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16777232 # 0x1000010 +; CHECK-NEXT: .long 58 # BTF_KIND_VAR(id = 7) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 8) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 9) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 64 # BTF_KIND_INT(id = 10) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 69 # BTF_KIND_VAR(id = 11) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 71 # BTF_KIND_DATASEC(id = 12) +; CHECK-NEXT: .long 251658242 # 0xf000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long foo.b +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long a +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/home/yhs/work/tests/llvm/bug/test.c" # string offset=15 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "short" # string offset=52 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo.b" # string offset=58 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=64 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=69 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "maps" # string offset=71 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!7} +!llvm.module.flags = !{!18, !19, !20} +!llvm.ident = !{!21} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !15, isLocal: true, isDefinition: true) +!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8) +!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!4 = !DISubroutineType(types: !5) +!5 = !{!6} +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None) +!8 = !{} +!9 = !{!0, !10} +!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression()) +!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true) +!12 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13) +!13 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !14) +!14 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!15 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !16) +!16 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !17) +!17 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) +!18 = !{i32 2, !"Dwarf Version", i32 4} +!19 = !{i32 2, !"Debug Info Version", i32 3} +!20 = !{i32 1, !"wchar_size", i32 4} +!21 = !{!"clang version 8.0.20181009 "} +!22 = !DILocation(line: 4, column: 10, scope: !2) +!23 = !{!24, !24, i64 0} +!24 = !{!"omnipotent char", !25, i64 0} +!25 = !{!"Simple C/C++ TBAA"} +!26 = !DILocation(line: 4, column: 14, scope: !2) +!27 = !{!28, !28, i64 0} +!28 = !{!"short", !24, i64 0} +!29 = !DILocation(line: 4, column: 12, scope: !2) +!30 = !DILocation(line: 4, column: 3, scope: !2) diff --git a/llvm/test/CodeGen/SBF/BTF/static-var-readonly.ll b/llvm/test/CodeGen/SBF/BTF/static-var-readonly.ll new file mode 100644 index 00000000000000..9358f348677726 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/static-var-readonly.ll @@ -0,0 +1,137 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; static volatile const char a; +; int foo() { +; static volatile const short b = 3; +; return a + b; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@foo.b = internal constant i16 3, align 2, !dbg !0 +@a = internal constant i8 0, align 1, !dbg !10 + +; Function Attrs: norecurse nounwind +define dso_local i32 @foo() local_unnamed_addr #0 !dbg !2 { + %1 = load volatile i8, i8* @a, align 1, !dbg !22, !tbaa !23 + %2 = sext i8 %1 to i32, !dbg !22 + %3 = load volatile i16, i16* @foo.b, align 2, !dbg !26, !tbaa !27 + %4 = sext i16 %3 to i32, !dbg !26 + %5 = add nsw i32 %4, %2, !dbg !29 + ret i32 %5, !dbg !30 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 188 +; CHECK-NEXT: .long 188 +; CHECK-NEXT: .long 79 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 4) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 5) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 52 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16777232 # 0x1000010 +; CHECK-NEXT: .long 58 # BTF_KIND_VAR(id = 7) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 8) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 9) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 64 # BTF_KIND_INT(id = 10) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 69 # BTF_KIND_VAR(id = 11) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 71 # BTF_KIND_DATASEC(id = 12) +; CHECK-NEXT: .long 251658242 # 0xf000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long foo.b +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long a +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/home/yhs/work/tests/llvm/bug/test.c" # string offset=15 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "short" # string offset=52 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo.b" # string offset=58 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=64 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=69 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".rodata" # string offset=71 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!7} +!llvm.module.flags = !{!18, !19, !20} +!llvm.ident = !{!21} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !15, isLocal: true, isDefinition: true) +!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8) +!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!4 = !DISubroutineType(types: !5) +!5 = !{!6} +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None) +!8 = !{} +!9 = !{!0, !10} +!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression()) +!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true) +!12 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13) +!13 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !14) +!14 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!15 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !16) +!16 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !17) +!17 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) +!18 = !{i32 2, !"Dwarf Version", i32 4} +!19 = !{i32 2, !"Debug Info Version", i32 3} +!20 = !{i32 1, !"wchar_size", i32 4} +!21 = !{!"clang version 8.0.20181009 "} +!22 = !DILocation(line: 4, column: 10, scope: !2) +!23 = !{!24, !24, i64 0} +!24 = !{!"omnipotent char", !25, i64 0} +!25 = !{!"Simple C/C++ TBAA"} +!26 = !DILocation(line: 4, column: 14, scope: !2) +!27 = !{!28, !28, i64 0} +!28 = !{!"short", !24, i64 0} +!29 = !DILocation(line: 4, column: 12, scope: !2) +!30 = !DILocation(line: 4, column: 3, scope: !2) diff --git a/llvm/test/CodeGen/SBF/BTF/static-var-sec.ll b/llvm/test/CodeGen/SBF/BTF/static-var-sec.ll new file mode 100644 index 00000000000000..81461c8a88b5f2 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/static-var-sec.ll @@ -0,0 +1,129 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; static volatile char a __attribute__((section("maps"))); +; int foo() { +; static volatile short b __attribute__((section("maps"))); +; return a + b; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@foo.b = internal global i16 0, section "maps", align 2, !dbg !0 +@a = internal global i8 0, section "maps", align 1, !dbg !10 + +; Function Attrs: norecurse nounwind +define dso_local i32 @foo() local_unnamed_addr #0 !dbg !2 { + %1 = load volatile i8, i8* @a, align 1, !dbg !20, !tbaa !21 + %2 = sext i8 %1 to i32, !dbg !20 + %3 = load volatile i16, i16* @foo.b, align 2, !dbg !24, !tbaa !25 + %4 = sext i16 %3 to i32, !dbg !24 + %5 = add nsw i32 %4, %2, !dbg !27 + ret i32 %5, !dbg !28 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 164 +; CHECK-NEXT: .long 164 +; CHECK-NEXT: .long 76 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 4) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 52 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16777232 # 0x1000010 +; CHECK-NEXT: .long 58 # BTF_KIND_VAR(id = 6) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 7) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 64 # BTF_KIND_INT(id = 8) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 69 # BTF_KIND_VAR(id = 9) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 71 # BTF_KIND_DATASEC(id = 10) +; CHECK-NEXT: .long 251658242 # 0xf000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long foo.b +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long a +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/home/yhs/work/tests/llvm/bug/test.c" # string offset=15 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "short" # string offset=52 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo.b" # string offset=58 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=64 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=69 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "maps" # string offset=71 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!7} +!llvm.module.flags = !{!16, !17, !18} +!llvm.ident = !{!19} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !14, isLocal: true, isDefinition: true) +!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8) +!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!4 = !DISubroutineType(types: !5) +!5 = !{!6} +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None) +!8 = !{} +!9 = !{!0, !10} +!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression()) +!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true) +!12 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !13) +!13 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!14 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !15) +!15 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{i32 1, !"wchar_size", i32 4} +!19 = !{!"clang version 8.0.20181009 "} +!20 = !DILocation(line: 4, column: 10, scope: !2) +!21 = !{!22, !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 4, column: 14, scope: !2) +!25 = !{!26, !26, i64 0} +!26 = !{!"short", !22, i64 0} +!27 = !DILocation(line: 4, column: 12, scope: !2) +!28 = !DILocation(line: 4, column: 3, scope: !2) diff --git a/llvm/test/CodeGen/SBF/BTF/static-var-zerolen-array.ll b/llvm/test/CodeGen/SBF/BTF/static-var-zerolen-array.ll new file mode 100644 index 00000000000000..dc90823d0369cb --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/static-var-zerolen-array.ll @@ -0,0 +1,141 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct t { +; int a; +; int b; +; char c[]; +; }; +; static volatile struct t sv = {3, 4, "abcdefghi"}; +; int test() { return sv.a; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@sv = internal global { i32, i32, [10 x i8] } { i32 3, i32 4, [10 x i8] c"abcdefghi\00" }, align 4, !dbg !0 + +; Function Attrs: norecurse nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !21 { + %1 = load volatile i32, i32* getelementptr inbounds ({ i32, i32, [10 x i8] }, { i32, i32, [10 x i8] }* @sv, i64 0, i32 0), align 4, !dbg !24, !tbaa !25 + ret i32 %1, !dbg !29 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 196 +; CHECK-NEXT: .long 196 +; CHECK-NEXT: .long 95 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 4) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 53 # BTF_KIND_STRUCT(id = 5) +; CHECK-NEXT: .long 67108867 # 0x4000003 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 55 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 57 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 59 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 64 # 0x40 +; CHECK-NEXT: .long 61 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 7) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 66 # BTF_KIND_INT(id = 8) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 86 # BTF_KIND_VAR(id = 9) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 89 # BTF_KIND_DATASEC(id = 10) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long sv +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "test" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/home/yhs/work/tests/llvm/bug/test.c" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 116 # string offset=53 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=55 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 98 # string offset=57 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 99 # string offset=59 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=61 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=66 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "sv" # string offset=86 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".data" # string offset=89 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!17, !18, !19} +!llvm.ident = !{!20} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "sv", scope: !2, file: !3, line: 6, type: !6, isLocal: true, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !7) +!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !3, line: 1, size: 64, elements: !8) +!8 = !{!9, !11, !12} +!9 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !7, file: !3, line: 2, baseType: !10, size: 32) +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !7, file: !3, line: 3, baseType: !10, size: 32, offset: 32) +!12 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !7, file: !3, line: 4, baseType: !13, offset: 64) +!13 = !DICompositeType(tag: DW_TAG_array_type, baseType: !14, elements: !15) +!14 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!15 = !{!16} +!16 = !DISubrange(count: -1) +!17 = !{i32 2, !"Dwarf Version", i32 4} +!18 = !{i32 2, !"Debug Info Version", i32 3} +!19 = !{i32 1, !"wchar_size", i32 4} +!20 = !{!"clang version 8.0.20181009 "} +!21 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 7, type: !22, isLocal: false, isDefinition: true, scopeLine: 7, isOptimized: true, unit: !2, retainedNodes: !4) +!22 = !DISubroutineType(types: !23) +!23 = !{!10} +!24 = !DILocation(line: 7, column: 24, scope: !21) +!25 = !{!26, !26, i64 0} +!26 = !{!"int", !27, i64 0} +!27 = !{!"omnipotent char", !28, i64 0} +!28 = !{!"Simple C/C++ TBAA"} +!29 = !DILocation(line: 7, column: 14, scope: !21) diff --git a/llvm/test/CodeGen/SBF/BTF/static-var.ll b/llvm/test/CodeGen/SBF/BTF/static-var.ll new file mode 100644 index 00000000000000..2ba7957b7af85f --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/static-var.ll @@ -0,0 +1,129 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; static volatile char a; +; int foo() { +; static volatile short b; +; return a + b; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@foo.b = internal global i16 0, align 2, !dbg !0 +@a = internal global i8 0, align 1, !dbg !10 + +; Function Attrs: norecurse nounwind +define dso_local i32 @foo() local_unnamed_addr #0 !dbg !2 { + %1 = load volatile i8, i8* @a, align 1, !dbg !20, !tbaa !21 + %2 = sext i8 %1 to i32, !dbg !20 + %3 = load volatile i16, i16* @foo.b, align 2, !dbg !24, !tbaa !25 + %4 = sext i16 %3 to i32, !dbg !24 + %5 = add nsw i32 %4, %2, !dbg !27 + ret i32 %5, !dbg !28 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 164 +; CHECK-NEXT: .long 164 +; CHECK-NEXT: .long 76 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 4) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 52 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16777232 # 0x1000010 +; CHECK-NEXT: .long 58 # BTF_KIND_VAR(id = 6) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 7) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 64 # BTF_KIND_INT(id = 8) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 69 # BTF_KIND_VAR(id = 9) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 71 # BTF_KIND_DATASEC(id = 10) +; CHECK-NEXT: .long 251658242 # 0xf000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long foo.b +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long a +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/home/yhs/work/tests/llvm/bug/test.c" # string offset=15 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "short" # string offset=52 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo.b" # string offset=58 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=64 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=69 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".bss" # string offset=71 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!7} +!llvm.module.flags = !{!16, !17, !18} +!llvm.ident = !{!19} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !14, isLocal: true, isDefinition: true) +!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8) +!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug") +!4 = !DISubroutineType(types: !5) +!5 = !{!6} +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None) +!8 = !{} +!9 = !{!0, !10} +!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression()) +!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true) +!12 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !13) +!13 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!14 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !15) +!15 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{i32 1, !"wchar_size", i32 4} +!19 = !{!"clang version 8.0.20181009 "} +!20 = !DILocation(line: 4, column: 10, scope: !2) +!21 = !{!22, !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 4, column: 14, scope: !2) +!25 = !{!26, !26, i64 0} +!26 = !{!"short", !22, i64 0} +!27 = !DILocation(line: 4, column: 12, scope: !2) +!28 = !DILocation(line: 4, column: 3, scope: !2) diff --git a/llvm/test/CodeGen/SBF/BTF/struct-anon-2.ll b/llvm/test/CodeGen/SBF/BTF/struct-anon-2.ll new file mode 100644 index 00000000000000..0ae5c89af2b082 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/struct-anon-2.ll @@ -0,0 +1,105 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; struct s1 { +; struct { int A1; } a1; +; struct { long B1; } *b1; +; }; +; int f1(struct s1 *s1) { return 0; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.s1 = type { %struct.anon, %struct.anon.0* } +%struct.anon = type { i32 } +%struct.anon.0 = type { i64 } + +; Function Attrs: norecurse nounwind readnone +define dso_local i32 @f1(%struct.s1* nocapture readnone %s1) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.s1* %s1, metadata !25, metadata !DIExpression()), !dbg !26 + ret i32 0, !dbg !27 +} + +; CHECK: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 2) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 64 # 0x40 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 13 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 5) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 6) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 17 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 20 # BTF_KIND_INT(id = 7) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 16777280 # 0x1000040 + +; CHECK: .ascii "s1" # string offset=1 +; CHECK: .ascii "a1" # string offset=4 +; CHECK: .ascii "b1" # string offset=7 +; CHECK: .ascii "A1" # string offset=10 +; CHECK: .ascii "int" # string offset=13 +; CHECK: .ascii "B1" # string offset=17 +; CHECK: .ascii "long int" # string offset=20 + + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git ef36f5143d83897cc6f59ff918769d29ad5a0612)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/btf/tmp") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git ef36f5143d83897cc6f59ff918769d29ad5a0612)"} +!7 = distinct !DISubprogram(name: "f1", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !24) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 128, elements: !13) +!13 = !{!14, !18} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !12, file: !1, line: 2, baseType: !15, size: 32) +!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !12, file: !1, line: 2, size: 32, elements: !16) +!16 = !{!17} +!17 = !DIDerivedType(tag: DW_TAG_member, name: "A1", scope: !15, file: !1, line: 2, baseType: !10, size: 32) +!18 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !12, file: !1, line: 3, baseType: !19, size: 64, offset: 64) +!19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64) +!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !12, file: !1, line: 3, size: 64, elements: !21) +!21 = !{!22} +!22 = !DIDerivedType(tag: DW_TAG_member, name: "B1", scope: !20, file: !1, line: 3, baseType: !23, size: 64) +!23 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed) +!24 = !{!25} +!25 = !DILocalVariable(name: "s1", arg: 1, scope: !7, file: !1, line: 5, type: !11) +!26 = !DILocation(line: 0, scope: !7) +!27 = !DILocation(line: 5, column: 25, scope: !7) diff --git a/llvm/test/CodeGen/SBF/BTF/struct-anon.ll b/llvm/test/CodeGen/SBF/BTF/struct-anon.ll new file mode 100644 index 00000000000000..150d711640171b --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/struct-anon.ll @@ -0,0 +1,64 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct { struct {int m;}; } a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.anon = type { %struct.anon.0 } +%struct.anon.0 = type { i32 } + +@a = common dso_local local_unnamed_addr global %struct.anon zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!13, !14, !15} +!llvm.ident = !{!16} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 2) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .byte 109 # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=3 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !3, line: 1, size: 32, elements: !7) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, scope: !6, file: !3, line: 1, baseType: !9, size: 32) +!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !6, file: !3, line: 1, size: 32, elements: !10) +!10 = !{!11} +!11 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !9, file: !3, line: 1, baseType: !12, size: 32) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{i32 1, !"wchar_size", i32 4} +!16 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/struct-basic.ll b/llvm/test/CodeGen/SBF/BTF/struct-basic.ll new file mode 100644 index 00000000000000..5e65eb38cdf174 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/struct-basic.ll @@ -0,0 +1,69 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct t1 {char m1; int n1;} a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t1 = type { i8, i32 } + +@a = common dso_local local_unnamed_addr global %struct.t1 zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!12, !13, !14} +!llvm.ident = !{!15} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 68 +; CHECK-NEXT: .long 68 +; CHECK-NEXT: .long 19 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 10 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 15 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "t1" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "m1" # string offset=4 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "n1" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=10 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=15 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 1, size: 64, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "m1", scope: !6, file: !3, line: 1, baseType: !9, size: 8) +!9 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "n1", scope: !6, file: !3, line: 1, baseType: !11, size: 32, offset: 32) +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !{i32 2, !"Dwarf Version", i32 4} +!13 = !{i32 2, !"Debug Info Version", i32 3} +!14 = !{i32 1, !"wchar_size", i32 4} +!15 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} diff --git a/llvm/test/CodeGen/SBF/BTF/struct-bitfield-typedef.ll b/llvm/test/CodeGen/SBF/BTF/struct-bitfield-typedef.ll new file mode 100644 index 00000000000000..00cb3a3eb529ab --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/struct-bitfield-typedef.ll @@ -0,0 +1,87 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; typedef int _int; +; typedef _int __int; +; struct {char m:2; __int n:3; char p;} a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.anon = type { i8, i8, [2 x i8] } + +@a = common dso_local local_unnamed_addr global %struct.anon zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!15, !16, !17} +!llvm.ident = !{!18} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 104 +; CHECK-NEXT: .long 104 +; CHECK-NEXT: .long 27 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 2214592515 # 0x84000003 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 50331650 # 0x3000002 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 8 # 0x8 +; CHECK-NEXT: .long 7 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 12 # BTF_KIND_TYPEDEF(id = 3) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 18 # BTF_KIND_TYPEDEF(id = 4) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 23 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .byte 109 # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 110 # string offset=3 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 112 # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__int" # string offset=12 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "_int" # string offset=18 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=23 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 3, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !3, line: 3, size: 32, elements: !7) +!7 = !{!8, !10, !14} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !6, file: !3, line: 3, baseType: !9, size: 2, flags: DIFlagBitField, extraData: i64 0) +!9 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "n", scope: !6, file: !3, line: 3, baseType: !11, size: 3, offset: 2, flags: DIFlagBitField, extraData: i64 0) +!11 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !3, line: 2, baseType: !12) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !3, line: 1, baseType: !13) +!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!14 = !DIDerivedType(tag: DW_TAG_member, name: "p", scope: !6, file: !3, line: 3, baseType: !9, size: 8, offset: 8) +!15 = !{i32 2, !"Dwarf Version", i32 4} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{i32 1, !"wchar_size", i32 4} +!18 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} diff --git a/llvm/test/CodeGen/SBF/BTF/struct-enum.ll b/llvm/test/CodeGen/SBF/BTF/struct-enum.ll new file mode 100644 index 00000000000000..368b1241b9cb0d --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/struct-enum.ll @@ -0,0 +1,74 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; enum t1 { A , B }; +; struct t2 { enum t1 m:2; enum t1 n; } a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t2 = type { i8, i32 } + +@a = common dso_local local_unnamed_addr global %struct.t2 zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!15, !16, !17} +!llvm.ident = !{!18} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 15 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 2214592514 # 0x84000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 8 # BTF_KIND_ENUM(id = 2) +; CHECK-NEXT: .long 100663298 # 0x6000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 13 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "t2" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 109 # string offset=4 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 110 # string offset=6 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "t1" # string offset=8 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 65 # string offset=11 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 66 # string offset=13 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !11, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !10, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{!5} +!5 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "t1", file: !3, line: 1, baseType: !6, size: 32, elements: !7) +!6 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!7 = !{!8, !9} +!8 = !DIEnumerator(name: "A", value: 0, isUnsigned: true) +!9 = !DIEnumerator(name: "B", value: 1, isUnsigned: true) +!10 = !{!0} +!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", file: !3, line: 2, size: 64, elements: !12) +!12 = !{!13, !14} +!13 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !11, file: !3, line: 2, baseType: !5, size: 2, flags: DIFlagBitField, extraData: i64 0) +!14 = !DIDerivedType(tag: DW_TAG_member, name: "n", scope: !11, file: !3, line: 2, baseType: !5, size: 32, offset: 32) +!15 = !{i32 2, !"Dwarf Version", i32 4} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{i32 1, !"wchar_size", i32 4} +!18 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/tag-1.ll b/llvm/test/CodeGen/SBF/BTF/tag-1.ll new file mode 100644 index 00000000000000..9c2d16d83eb1bb --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/tag-1.ll @@ -0,0 +1,90 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; #define __tag1 __attribute__((btf_decl_tag("tag1"))) +; #define __tag2 __attribute__((btf_decl_tag("tag2"))) +; struct t1 { +; int a1; +; int a2 __tag1 __tag2; +; } __tag1 __tag2; +; struct t1 g1 __tag1 __tag2; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t1 = type { i32, i32 } + +@g1 = dso_local local_unnamed_addr global %struct.t1 zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!14, !15, !16, !17} +!llvm.ident = !{!18} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g1", scope: !2, file: !3, line: 7, type: !6, isLocal: false, isDefinition: true, annotations: !11) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 825661b8e31d0b29d78178df1e518949dfec9f9a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 3, size: 64, elements: !7, annotations: !11) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !6, file: !3, line: 4, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !6, file: !3, line: 5, baseType: !9, size: 32, offset: 32, annotations: !11) +!11 = !{!12, !13} +!12 = !{!"btf_decl_tag", !"tag1"} +!13 = !{!"btf_decl_tag", !"tag2"} +!14 = !{i32 7, !"Dwarf Version", i32 4} +!15 = !{i32 2, !"Debug Info Version", i32 3} +!16 = !{i32 1, !"wchar_size", i32 4} +!17 = !{i32 7, !"frame-pointer", i32 2} +!18 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 825661b8e31d0b29d78178df1e518949dfec9f9a)"} + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 10 # BTF_KIND_DECL_TAG(id = 2) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 4294967295 +; CHECK-NEXT: .long 15 # BTF_KIND_DECL_TAG(id = 3) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 4294967295 +; CHECK-NEXT: .long 20 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 10 # BTF_KIND_DECL_TAG(id = 5) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 15 # BTF_KIND_DECL_TAG(id = 6) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 24 # BTF_KIND_VAR(id = 7) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 10 # BTF_KIND_DECL_TAG(id = 8) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 4294967295 +; CHECK-NEXT: .long 15 # BTF_KIND_DECL_TAG(id = 9) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 4294967295 + +; CHECK: .ascii "t1" # string offset=1 +; CHECK: .ascii "a1" # string offset=4 +; CHECK: .ascii "a2" # string offset=7 +; CHECK: .ascii "tag1" # string offset=10 +; CHECK: .ascii "tag2" # string offset=15 +; CHECK: .ascii "int" # string offset=20 +; CHECK: .ascii "g1" # string offset=24 diff --git a/llvm/test/CodeGen/SBF/BTF/tag-2.ll b/llvm/test/CodeGen/SBF/BTF/tag-2.ll new file mode 100644 index 00000000000000..5973c06365291c --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/tag-2.ll @@ -0,0 +1,125 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; #define __tag1 __attribute__((btf_decl_tag("tag1"))) +; #define __tag2 __attribute__((btf_decl_tag("tag2"))) +; extern int bar(int a1, int a2) __tag1 __tag2; +; int __tag1 foo(int arg1, int *arg2 __tag1) { +; ; return arg1 + *arg2 + bar(arg1, arg1 + 1); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +; Function Attrs: nounwind +define dso_local i32 @foo(i32 %arg1, i32* nocapture readonly %arg2) local_unnamed_addr #0 !dbg !8 { +entry: + call void @llvm.dbg.value(metadata i32 %arg1, metadata !14, metadata !DIExpression()), !dbg !18 + call void @llvm.dbg.value(metadata i32* %arg2, metadata !15, metadata !DIExpression()), !dbg !18 + %0 = load i32, i32* %arg2, align 4, !dbg !19, !tbaa !20 + %add = add nsw i32 %0, %arg1, !dbg !24 + %add1 = add nsw i32 %arg1, 1, !dbg !25 + %call = tail call i32 @bar(i32 %arg1, i32 %add1) #3, !dbg !26 + %add2 = add nsw i32 %add, %call, !dbg !27 + ret i32 %add2, !dbg !28 +} + +declare !dbg !29 dso_local i32 @bar(i32, i32) local_unnamed_addr #1 + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #2 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.0 (https://github.com/llvm/llvm-project.git 4be11596b26383c6666f471f07463a3f79e11964)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{i32 7, !"frame-pointer", i32 2} +!7 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git 4be11596b26383c6666f471f07463a3f79e11964)"} +!8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 4, type: !9, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13, annotations: !16) +!9 = !DISubroutineType(types: !10) +!10 = !{!11, !11, !12} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64) +!13 = !{!14, !15} +!14 = !DILocalVariable(name: "arg1", arg: 1, scope: !8, file: !1, line: 4, type: !11) +!15 = !DILocalVariable(name: "arg2", arg: 2, scope: !8, file: !1, line: 4, type: !12, annotations: !16) +!16 = !{!17} +!17 = !{!"btf_decl_tag", !"tag1"} +!18 = !DILocation(line: 0, scope: !8) +!19 = !DILocation(line: 5, column: 17, scope: !8) +!20 = !{!21, !21, i64 0} +!21 = !{!"int", !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 5, column: 15, scope: !8) +!25 = !DILocation(line: 5, column: 40, scope: !8) +!26 = !DILocation(line: 5, column: 25, scope: !8) +!27 = !DILocation(line: 5, column: 23, scope: !8) +!28 = !DILocation(line: 5, column: 3, scope: !8) +!29 = !DISubprogram(name: "bar", scope: !1, file: !1, line: 3, type: !30, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2, annotations: !32) +!30 = !DISubroutineType(types: !31) +!31 = !{!11, !11, !11} +!32 = !{!17, !33} +!33 = !{!"btf_decl_tag", !"tag2"} + +; CHECK: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3) +; CHECK-NEXT: .long 218103810 # 0xd000002 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 15 # BTF_KIND_FUNC(id = 4) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 19 # BTF_KIND_DECL_TAG(id = 5) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 19 # BTF_KIND_DECL_TAG(id = 6) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 4294967295 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 7) +; CHECK-NEXT: .long 218103810 # 0xd000002 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 72 # BTF_KIND_FUNC(id = 8) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 19 # BTF_KIND_DECL_TAG(id = 9) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 4294967295 +; CHECK-NEXT: .long 76 # BTF_KIND_DECL_TAG(id = 10) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 4294967295 + +; CHECK: .ascii "int" # string offset=1 +; CHECK: .ascii "arg1" # string offset=5 +; CHECK: .ascii "arg2" # string offset=10 +; CHECK: .ascii "foo" # string offset=15 +; CHECK: .ascii "tag1" # string offset=19 +; CHECK: .ascii "bar" # string offset=72 +; CHECK: .ascii "tag2" # string offset=76 diff --git a/llvm/test/CodeGen/SBF/BTF/tag-typedef.ll b/llvm/test/CodeGen/SBF/BTF/tag-typedef.ll new file mode 100644 index 00000000000000..d8acdd73e92936 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/tag-typedef.ll @@ -0,0 +1,86 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; #define __tag1 __attribute__((btf_decl_tag("tag1"))) +; typedef struct { int a; } __s __tag1; +; typedef unsigned * __u __tag1; +; __s a; +; __u u; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.__s = type { i32 } + +@a = dso_local local_unnamed_addr global %struct.__s zeroinitializer, align 4, !dbg !0 +@u = dso_local local_unnamed_addr global i32* null, align 8, !dbg !5 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!17, !18, !19, !20} +!llvm.ident = !{!21} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 4, type: !12, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 14.0.0 (https://github.com/llvm/llvm-project.git 219b26fbcd70273ddfd4ead9387f7c69b7eb4570)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag") +!4 = !{!0, !5} +!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) +!6 = distinct !DIGlobalVariable(name: "u", scope: !2, file: !3, line: 5, type: !7, isLocal: false, isDefinition: true) +!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "__u", file: !3, line: 3, baseType: !8, annotations: !10) +!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64) +!9 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!10 = !{!11} +!11 = !{!"btf_decl_tag", !"tag1"} +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s", file: !3, line: 2, baseType: !13, annotations: !10) +!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !3, line: 2, size: 32, elements: !14) +!14 = !{!15} +!15 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !13, file: !3, line: 2, baseType: !16, size: 32) +!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!17 = !{i32 7, !"Dwarf Version", i32 4} +!18 = !{i32 2, !"Debug Info Version", i32 3} +!19 = !{i32 1, !"wchar_size", i32 4} +!20 = !{i32 7, !"frame-pointer", i32 2} +!21 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git 219b26fbcd70273ddfd4ead9387f7c69b7eb4570)"} + +; CHECK: .long 1 # BTF_KIND_TYPEDEF(id = 1) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 5 # BTF_KIND_DECL_TAG(id = 2) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 4294967295 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 12 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 10 # BTF_KIND_VAR(id = 5) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16 # BTF_KIND_TYPEDEF(id = 6) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 5 # BTF_KIND_DECL_TAG(id = 7) +; CHECK-NEXT: .long 285212672 # 0x11000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 4294967295 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 8) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 20 # BTF_KIND_INT(id = 9) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 + +; CHECK: .ascii "__s" # string offset=1 +; CHECK: .ascii "tag1" # string offset=5 +; CHECK: .byte 97 # string offset=10 +; CHECK: .ascii "int" # string offset=12 +; CHECK: .ascii "__u" # string offset=16 +; CHECK: .ascii "unsigned int" # string offset=20 + diff --git a/llvm/test/CodeGen/SBF/BTF/type-tag-fixup-fwd.ll b/llvm/test/CodeGen/SBF/BTF/type-tag-fixup-fwd.ll new file mode 100644 index 00000000000000..2523959158760d --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/type-tag-fixup-fwd.ll @@ -0,0 +1,130 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; +; struct foo; +; struct map_value { +; struct foo __tag2 __tag1 *ptr; +; }; +; void func(struct map_value *); +; void test(void) +; { +; struct map_value v = {}; +; func(&v); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +%struct.map_value = type { %struct.foo* } +%struct.foo = type opaque + +; Function Attrs: nounwind +define dso_local void @test() local_unnamed_addr #0 !dbg !7 { +entry: + %v = alloca %struct.map_value, align 8 + %0 = bitcast %struct.map_value* %v to i8*, !dbg !20 + call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #4, !dbg !20 + call void @llvm.dbg.declare(metadata %struct.map_value* %v, metadata !11, metadata !DIExpression()), !dbg !21 + %1 = bitcast %struct.map_value* %v to i64*, !dbg !21 + store i64 0, i64* %1, align 8, !dbg !21 + call void @func(%struct.map_value* noundef nonnull %v) #4, !dbg !22 + call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #4, !dbg !23 + ret void, !dbg !23 +} + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 62 # BTF_KIND_STRUCT(id = 5) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 76 # BTF_KIND_TYPE_TAG(id = 6) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 81 # BTF_KIND_TYPE_TAG(id = 7) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 8) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 86 # BTF_KIND_FWD(id = 9) +; CHECK-NEXT: .long 117440512 # 0x7000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 90 # BTF_KIND_FUNC(id = 10) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 3 + +; CHECK: .ascii "test" # string offset=1 +; CHECK: .ascii "map_value" # string offset=62 +; CHECK: .ascii "ptr" # string offset=72 +; CHECK: .ascii "tag2" # string offset=76 +; CHECK: .ascii "tag1" # string offset=81 +; CHECK: .ascii "foo" # string offset=86 +; CHECK: .ascii "func" # string offset=90 + +; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: mustprogress nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +declare !dbg !24 dso_local void @func(%struct.map_value* noundef) local_unnamed_addr #3 + +; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { argmemonly mustprogress nofree nosync nounwind willreturn } +attributes #2 = { mustprogress nofree nosync nounwind readnone speculatable willreturn } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag_type", checksumkind: CSK_MD5, checksum: "7735a89e98603fee29d352a8e9db5acb") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 7, !"frame-pointer", i32 2} +!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 9, type: !8, scopeLine: 10, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{!11} +!11 = !DILocalVariable(name: "v", scope: !7, file: !1, line: 11, type: !12) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: !1, line: 5, size: 64, elements: !13) +!13 = !{!14} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !12, file: !1, line: 6, baseType: !15, size: 64) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !17) +!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, flags: DIFlagFwdDecl) +!17 = !{!18, !19} +!18 = !{!"btf_type_tag", !"tag2"} +!19 = !{!"btf_type_tag", !"tag1"} +!20 = !DILocation(line: 11, column: 9, scope: !7) +!21 = !DILocation(line: 11, column: 26, scope: !7) +!22 = !DILocation(line: 12, column: 9, scope: !7) +!23 = !DILocation(line: 13, column: 1, scope: !7) +!24 = !DISubprogram(name: "func", scope: !1, file: !1, line: 8, type: !25, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !28) +!25 = !DISubroutineType(types: !26) +!26 = !{null, !27} +!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!28 = !{} diff --git a/llvm/test/CodeGen/SBF/BTF/type-tag-fixup-resolved.ll b/llvm/test/CodeGen/SBF/BTF/type-tag-fixup-resolved.ll new file mode 100644 index 00000000000000..533047f8fb7ad7 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/type-tag-fixup-resolved.ll @@ -0,0 +1,150 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; +; struct foo { +; int i; +; }; +; struct map_value { +; struct foo __tag2 __tag1 *ptr; +; }; +; void func(struct map_value *, struct foo *); +; void test(void) +; { +; struct map_value v = {}; +; func(&v, v.ptr); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +%struct.map_value = type { %struct.foo* } +%struct.foo = type { i32 } + +; Function Attrs: nounwind +define dso_local void @test() local_unnamed_addr #0 !dbg !7 { +entry: + %v = alloca %struct.map_value, align 8 + %0 = bitcast %struct.map_value* %v to i8*, !dbg !23 + call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #4, !dbg !23 + call void @llvm.dbg.declare(metadata %struct.map_value* %v, metadata !11, metadata !DIExpression()), !dbg !24 + %1 = bitcast %struct.map_value* %v to i64*, !dbg !24 + store i64 0, i64* %1, align 8, !dbg !24 + call void @func(%struct.map_value* noundef nonnull %v, %struct.foo* noundef null) #4, !dbg !25 + call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #4, !dbg !26 + ret void, !dbg !26 +} + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3) +; CHECK-NEXT: .long 218103810 # 0xd000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 63 # BTF_KIND_STRUCT(id = 5) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 73 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 6) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 7) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 77 # BTF_KIND_STRUCT(id = 8) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 81 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 83 # BTF_KIND_INT(id = 9) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 87 # BTF_KIND_FUNC(id = 10) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 92 # BTF_KIND_TYPE_TAG(id = 11) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 97 # BTF_KIND_TYPE_TAG(id = 12) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 11 + +; CHECK: .ascii "test" # string offset=1 +; CHECK: .ascii "map_value" # string offset=63 +; CHECK: .ascii "ptr" # string offset=73 +; CHECK: .ascii "foo" # string offset=77 +; CHECK: .byte 105 # string offset=81 +; CHECK: .ascii "int" # string offset=83 +; CHECK: .ascii "func" # string offset=87 +; CHECK: .ascii "tag2" # string offset=92 +; CHECK: .ascii "tag1" # string offset=97 + +; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: mustprogress nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +declare !dbg !27 dso_local void @func(%struct.map_value* noundef, %struct.foo* noundef) local_unnamed_addr #3 + +; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { argmemonly mustprogress nofree nosync nounwind willreturn } +attributes #2 = { mustprogress nofree nosync nounwind readnone speculatable willreturn } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp//home/yhs/work/tests/llvm/btf_tag_type", checksumkind: CSK_MD5, checksum: "8b3b8281c3b4240403467e0c9461251d") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 7, !"frame-pointer", i32 2} +!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 11, type: !8, scopeLine: 12, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{!11} +!11 = !DILocalVariable(name: "v", scope: !7, file: !1, line: 13, type: !12) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: !1, line: 7, size: 64, elements: !13) +!13 = !{!14} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !12, file: !1, line: 8, baseType: !15, size: 64) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !20) +!16 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, size: 32, elements: !17) +!17 = !{!18} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !16, file: !1, line: 5, baseType: !19, size: 32) +!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!20 = !{!21, !22} +!21 = !{!"btf_type_tag", !"tag2"} +!22 = !{!"btf_type_tag", !"tag1"} +!23 = !DILocation(line: 13, column: 9, scope: !7) +!24 = !DILocation(line: 13, column: 26, scope: !7) +!25 = !DILocation(line: 14, column: 9, scope: !7) +!26 = !DILocation(line: 15, column: 1, scope: !7) +!27 = !DISubprogram(name: "func", scope: !1, file: !1, line: 10, type: !28, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !32) +!28 = !DISubroutineType(types: !29) +!29 = !{null, !30, !31} +!30 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!32 = !{} diff --git a/llvm/test/CodeGen/SBF/BTF/type-tag-var.ll b/llvm/test/CodeGen/SBF/BTF/type-tag-var.ll new file mode 100644 index 00000000000000..d2d5932bcea2b5 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/type-tag-var.ll @@ -0,0 +1,62 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; int __tag1 * __tag1 __tag2 *g; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@g = dso_local local_unnamed_addr global i32** null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!12, !13, !14, !15} +!llvm.ident = !{!16} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 3, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 14.0.0 (https://github.com/llvm/llvm-project.git 077b2e0cf1e97c4d97ca5ceab3ec0192ed11c66e)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag_type") +!4 = !{!0} +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, annotations: !10) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, annotations: !8) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !{!9} +!9 = !{!"btf_type_tag", !"tag1"} +!10 = !{!9, !11} +!11 = !{!"btf_type_tag", !"tag2"} + +; CHECK: .long 1 # BTF_KIND_TYPE_TAG(id = 1) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 6 # BTF_KIND_TYPE_TAG(id = 2) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 3) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_TYPE_TAG(id = 4) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 5) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 11 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 15 # BTF_KIND_VAR(id = 7) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "tag1" # string offset=1 +; CHECK: .ascii "tag2" # string offset=6 +; CHECK: .ascii "int" # string offset=11 +; CHECK: .byte 103 # string offset=15 + +!12 = !{i32 7, !"Dwarf Version", i32 4} +!13 = !{i32 2, !"Debug Info Version", i32 3} +!14 = !{i32 1, !"wchar_size", i32 4} +!15 = !{i32 7, !"frame-pointer", i32 2} +!16 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git 077b2e0cf1e97c4d97ca5ceab3ec0192ed11c66e)"} diff --git a/llvm/test/CodeGen/SBF/BTF/uchar.ll b/llvm/test/CodeGen/SBF/BTF/uchar.ll new file mode 100644 index 00000000000000..80543f3715d953 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/uchar.ll @@ -0,0 +1,41 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; unsigned char a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i8 0, align 1, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 15 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 8 # 0x8 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "unsigned char" # string offset=1 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "unsigned char", size: 8, encoding: DW_ATE_unsigned_char) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} diff --git a/llvm/test/CodeGen/SBF/BTF/uint.ll b/llvm/test/CodeGen/SBF/BTF/uint.ll new file mode 100644 index 00000000000000..48419cc4742a87 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/uint.ll @@ -0,0 +1,41 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; unsigned a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32 0, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 14 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "unsigned int" # string offset=1 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/ulonglong.ll b/llvm/test/CodeGen/SBF/BTF/ulonglong.ll new file mode 100644 index 00000000000000..b631e64f581d41 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/ulonglong.ll @@ -0,0 +1,41 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; unsigned long long a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i64 0, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 64 # 0x40 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "long long unsigned int" # string offset=1 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/union-array-typedef.ll b/llvm/test/CodeGen/SBF/BTF/union-array-typedef.ll new file mode 100644 index 00000000000000..1e567314371427 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/union-array-typedef.ll @@ -0,0 +1,91 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; typedef int _int; +; union t {char m[4]; _int n;} a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%union.t = type { i32 } + +@a = common dso_local local_unnamed_addr global %union.t zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!16, !17, !18} +!llvm.ident = !{!19} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 120 +; CHECK-NEXT: .long 120 +; CHECK-NEXT: .long 41 +; CHECK-NEXT: .long 1 # BTF_KIND_UNION(id = 1) +; CHECK-NEXT: .long 83886082 # 0x5000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 7 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 3) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 12 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 32 # BTF_KIND_TYPEDEF(id = 5) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 37 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .byte 116 # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 109 # string offset=3 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 110 # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=12 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "_int" # string offset=32 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=37 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "t", file: !3, line: 2, size: 32, elements: !7) +!7 = !{!8, !13} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !6, file: !3, line: 2, baseType: !9, size: 32) +!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, elements: !11) +!10 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!11 = !{!12} +!12 = !DISubrange(count: 4) +!13 = !DIDerivedType(tag: DW_TAG_member, name: "n", scope: !6, file: !3, line: 2, baseType: !14, size: 32) +!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !3, line: 1, baseType: !15) +!15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{i32 1, !"wchar_size", i32 4} +!19 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} diff --git a/llvm/test/CodeGen/SBF/BTF/ushort.ll b/llvm/test/CodeGen/SBF/BTF/ushort.ll new file mode 100644 index 00000000000000..742c353fcdb15c --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/ushort.ll @@ -0,0 +1,41 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; unsigned short a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i16 0, align 2, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16 # 0x10 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "unsigned short" # string offset=1 +; CHECK-NEXT: .byte 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "unsigned short", size: 16, encoding: DW_ATE_unsigned) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} diff --git a/llvm/test/CodeGen/SBF/BTF/weak-global-2.ll b/llvm/test/CodeGen/SBF/BTF/weak-global-2.ll new file mode 100644 index 00000000000000..38a0b14721a1e3 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/weak-global-2.ll @@ -0,0 +1,65 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; char g __attribute__((weak)) = 2; +; int test() { +; return g; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@g = weak dso_local local_unnamed_addr global i8 2, align 1, !dbg !0 +; Function Attrs: norecurse nounwind readonly +define dso_local i32 @test() local_unnamed_addr #0 !dbg !11 { +entry: + %0 = load i8, i8* @g, align 1, !dbg !15, !tbaa !16 + %conv = sext i8 %0 to i32, !dbg !15 + ret i32 %conv, !dbg !19 +} + +; CHECK: .long 55 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 60 # BTF_KIND_VAR(id = 5) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 62 # BTF_KIND_DATASEC(id = 6) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long g +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "char" # string offset=55 +; CHECK: .byte 103 # string offset=60 +; CHECK: .ascii ".data" # string offset=62 + + +attributes #0 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git edf6717d8d30034da932b95350898e03c90a5082)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/global") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!7 = !{i32 7, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git edf6717d8d30034da932b95350898e03c90a5082)"} +!11 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 2, type: !12, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) +!12 = !DISubroutineType(types: !13) +!13 = !{!14} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DILocation(line: 3, column: 10, scope: !11) +!16 = !{!17, !17, i64 0} +!17 = !{!"omnipotent char", !18, i64 0} +!18 = !{!"Simple C/C++ TBAA"} +!19 = !DILocation(line: 3, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/BTF/weak-global-3.ll b/llvm/test/CodeGen/SBF/BTF/weak-global-3.ll new file mode 100644 index 00000000000000..f072e8cad453e0 --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/weak-global-3.ll @@ -0,0 +1,85 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; const volatile char g __attribute__((weak)) = 2; +; int test() { +; return g; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@g = weak_odr dso_local constant i8 2, align 1, !dbg !0 + +; Function Attrs: nofree norecurse nounwind willreturn +define dso_local i32 @test() local_unnamed_addr #0 !dbg !13 { +entry: + %0 = load volatile i8, i8* @g, align 1, !dbg !17, !tbaa !18 + %conv = sext i8 %0 to i32, !dbg !17 + ret i32 %conv, !dbg !21 +} + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 4) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 5) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 47 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 52 # BTF_KIND_VAR(id = 7) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 54 # BTF_KIND_DATASEC(id = 8) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long g +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "int" # string offset=1 +; CHECK: .ascii "test" # string offset=5 +; CHECK: .ascii "char" # string offset=47 +; CHECK: .byte 103 # string offset=52 +; CHECK: .ascii ".rodata" # string offset=54 + +attributes #0 = { nofree norecurse nounwind willreturn "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 9cc417cbca1cece0d55fa3d1e15682943a06139e)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/btf/tests") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !7) +!7 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !8) +!8 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!9 = !{i32 7, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 9cc417cbca1cece0d55fa3d1e15682943a06139e)"} +!13 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 2, type: !14, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) +!14 = !DISubroutineType(types: !15) +!15 = !{!16} +!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!17 = !DILocation(line: 3, column: 10, scope: !13) +!18 = !{!19, !19, i64 0} +!19 = !{!"omnipotent char", !20, i64 0} +!20 = !{!"Simple C/C++ TBAA"} +!21 = !DILocation(line: 3, column: 3, scope: !13) diff --git a/llvm/test/CodeGen/SBF/BTF/weak-global.ll b/llvm/test/CodeGen/SBF/BTF/weak-global.ll new file mode 100644 index 00000000000000..3116517f31c0bb --- /dev/null +++ b/llvm/test/CodeGen/SBF/BTF/weak-global.ll @@ -0,0 +1,64 @@ +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source code: +; char g __attribute__((weak)); +; int test() { +; return g; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@g = weak dso_local local_unnamed_addr global i8 0, align 1, !dbg !0 +; Function Attrs: norecurse nounwind readonly +define dso_local i32 @test() local_unnamed_addr #0 !dbg !11 { +entry: + %0 = load i8, i8* @g, align 1, !dbg !15, !tbaa !16 + %conv = sext i8 %0 to i32, !dbg !15 + ret i32 %conv, !dbg !19 +} + +; CHECK: .long 55 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777224 # 0x1000008 +; CHECK-NEXT: .long 60 # BTF_KIND_VAR(id = 5) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 62 # BTF_KIND_DATASEC(id = 6) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long g +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "char" # string offset=55 +; CHECK: .byte 103 # string offset=60 +; CHECK: .ascii ".bss" # string offset=62 + +attributes #0 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git edf6717d8d30034da932b95350898e03c90a5082)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/global") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!7 = !{i32 7, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git edf6717d8d30034da932b95350898e03c90a5082)"} +!11 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 2, type: !12, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) +!12 = !DISubroutineType(types: !13) +!13 = !{!14} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DILocation(line: 3, column: 10, scope: !11) +!16 = !{!17, !17, i64 0} +!17 = !{!"omnipotent char", !18, i64 0} +!18 = !{!"Simple C/C++ TBAA"} +!19 = !DILocation(line: 3, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/anon-struct-argument-pragma.ll b/llvm/test/CodeGen/SBF/CORE/anon-struct-argument-pragma.ll new file mode 100644 index 00000000000000..3ccbaa1b5688d6 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/anon-struct-argument-pragma.ll @@ -0,0 +1,100 @@ +; RUN: opt -O2 -mtriple=sbf %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -o - %t1 | FileCheck %s +; +; Source: +; #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record) +; typedef struct { +; union { +; void *kernel; +; void *user; +; }; +; unsigned is_kernel : 1; +; } sockptr_t; +; #pragma clang attribute pop +; int test(sockptr_t *arg) { +; return arg->is_kernel; +; } +; Compilation flag: +; clang -target bpf -O2 -S -emit-llvm -g -Xclang -disable-llvm-passes test.c + +%struct.sockptr_t = type { %union.anon, i8 } +%union.anon = type { ptr } + +; Function Attrs: nounwind +define dso_local i32 @test(ptr noundef %arg) #0 !dbg !7 { +entry: + %arg.addr = alloca ptr, align 8 + store ptr %arg, ptr %arg.addr, align 8, !tbaa !25 + call void @llvm.dbg.declare(metadata ptr %arg.addr, metadata !24, metadata !DIExpression()), !dbg !29 + %0 = load ptr, ptr %arg.addr, align 8, !dbg !30, !tbaa !25 + %1 = call ptr @llvm.preserve.struct.access.index.p0.p0(ptr elementtype(%struct.sockptr_t) %0, i32 1, i32 1), !dbg !31, !llvm.preserve.access.index !13 + %bf.load = load i8, ptr %1, align 8, !dbg !31 + %bf.clear = and i8 %bf.load, 1, !dbg !31 + %bf.cast = zext i8 %bf.clear to i32, !dbg !31 + ret i32 %bf.cast, !dbg !32 +} + +; CHECK: .long 1 # BTF_KIND_TYPEDEF(id = 2) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 3) + +; CHECK: .ascii "sockptr_t" # string offset=1 +; CHECK: .ascii ".text" # string offset=59 +; CHECK: .ascii "0:1" # string offset=65 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 59 # Field reloc section string offset=59 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp[[#]] +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 65 +; CHECK-NEXT: .long 0 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nocallback nofree nosync nounwind readnone willreturn +declare ptr @llvm.preserve.struct.access.index.p0.p0(ptr, i32 immarg, i32 immarg) #2 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nocallback nofree nosync nounwind readnone willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git d81a8759c969344c1e96992aab30f5b5a9d5ffd3)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/test/anon", checksumkind: CSK_MD5, checksum: "7ba33bf2146cc86b1c8396f6d3eace81") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 7, !"frame-pointer", i32 2} +!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git d81a8759c969344c1e96992aab30f5b5a9d5ffd3)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 10, type: !8, scopeLine: 10, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !23) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "sockptr_t", file: !1, line: 8, baseType: !13) +!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !1, line: 2, size: 128, elements: !14) +!14 = !{!15, !21} +!15 = !DIDerivedType(tag: DW_TAG_member, scope: !13, file: !1, line: 3, baseType: !16, size: 64) +!16 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !13, file: !1, line: 3, size: 64, elements: !17) +!17 = !{!18, !20} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "kernel", scope: !16, file: !1, line: 4, baseType: !19, size: 64) +!19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!20 = !DIDerivedType(tag: DW_TAG_member, name: "user", scope: !16, file: !1, line: 5, baseType: !19, size: 64) +!21 = !DIDerivedType(tag: DW_TAG_member, name: "is_kernel", scope: !13, file: !1, line: 7, baseType: !22, size: 1, offset: 64, flags: DIFlagBitField, extraData: i64 64) +!22 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!23 = !{!24} +!24 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 10, type: !11) +!25 = !{!26, !26, i64 0} +!26 = !{!"any pointer", !27, i64 0} +!27 = !{!"omnipotent char", !28, i64 0} +!28 = !{!"Simple C/C++ TBAA"} +!29 = !DILocation(line: 10, column: 21, scope: !7) +!30 = !DILocation(line: 11, column: 10, scope: !7) +!31 = !DILocation(line: 11, column: 15, scope: !7) +!32 = !DILocation(line: 11, column: 3, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/anon-union-localvar-attr.ll b/llvm/test/CodeGen/SBF/CORE/anon-union-localvar-attr.ll new file mode 100644 index 00000000000000..b218747c304581 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/anon-union-localvar-attr.ll @@ -0,0 +1,124 @@ +; RUN: opt -O2 -mtriple=sbf %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -o - %t1 | FileCheck %s +; +; Source: +; typedef union { +; struct { +; void *kernel; +; void *user; +; }; +; unsigned is_kernel : 1; +; } __attribute__((preserve_access_index)) sockptr_t; +; void *foo(void); +; int test() { +; sockptr_t *arg = foo(); +; return __builtin_preserve_field_info(arg->is_kernel, 1); +; } +; Compilation flag: +; clang -target bpf -O2 -S -emit-llvm -g -Xclang -disable-llvm-passes test.c + +%union.sockptr_t = type { %struct.anon } +%struct.anon = type { ptr, ptr } + +; Function Attrs: nounwind +define dso_local i32 @test() #0 !dbg !7 { +entry: + %arg = alloca ptr, align 8 + call void @llvm.lifetime.start.p0(i64 8, ptr %arg) #6, !dbg !25 + call void @llvm.dbg.declare(metadata ptr %arg, metadata !12, metadata !DIExpression()), !dbg !26 + %call = call ptr @foo(), !dbg !27 + store ptr %call, ptr %arg, align 8, !dbg !26, !tbaa !28 + %0 = load ptr, ptr %arg, align 8, !dbg !32, !tbaa !28 + %1 = call ptr @llvm.preserve.struct.access.index.p0.p0(ptr elementtype(%union.sockptr_t) %0, i32 0, i32 1), !dbg !33, !llvm.preserve.access.index !15 + %2 = call i32 @llvm.bpf.preserve.field.info.p0(ptr %1, i64 1), !dbg !34 + call void @llvm.lifetime.end.p0(i64 8, ptr %arg) #6, !dbg !35 + ret i32 %2, !dbg !36 +} + +; CHECK: .long 56 # BTF_KIND_TYPEDEF(id = 7) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 0 # BTF_KIND_UNION(id = 8) + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "sockptr_t" # string offset=56 +; CHECK: .ascii "0:1" # string offset=101 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp[[#]] +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 101 +; CHECK-NEXT: .long 1 + +; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn +declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +declare !dbg !37 dso_local ptr @foo() #3 + +; Function Attrs: nocallback nofree nosync nounwind readnone willreturn +declare ptr @llvm.preserve.struct.access.index.p0.p0(ptr, i32 immarg, i32 immarg) #4 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0(ptr, i64 immarg) #5 + +; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn +declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { argmemonly nocallback nofree nosync nounwind willreturn } +attributes #2 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #4 = { nocallback nofree nosync nounwind readnone willreturn } +attributes #5 = { nounwind readnone } +attributes #6 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 8c7d5118961e7ffc0304126ec2122d21e2eb1f79)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/test/anon", checksumkind: CSK_MD5, checksum: "03904da5c5e53b14bb1effb6d9d5e025") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 7, !"frame-pointer", i32 2} +!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 8c7d5118961e7ffc0304126ec2122d21e2eb1f79)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 9, type: !8, scopeLine: 9, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DILocalVariable(name: "arg", scope: !7, file: !1, line: 10, type: !13) +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "sockptr_t", file: !1, line: 7, baseType: !15) +!15 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !1, line: 1, size: 128, elements: !16) +!16 = !{!17, !23} +!17 = !DIDerivedType(tag: DW_TAG_member, scope: !15, file: !1, line: 2, baseType: !18, size: 128) +!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !15, file: !1, line: 2, size: 128, elements: !19) +!19 = !{!20, !22} +!20 = !DIDerivedType(tag: DW_TAG_member, name: "kernel", scope: !18, file: !1, line: 3, baseType: !21, size: 64) +!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!22 = !DIDerivedType(tag: DW_TAG_member, name: "user", scope: !18, file: !1, line: 4, baseType: !21, size: 64, offset: 64) +!23 = !DIDerivedType(tag: DW_TAG_member, name: "is_kernel", scope: !15, file: !1, line: 6, baseType: !24, size: 1, flags: DIFlagBitField, extraData: i64 0) +!24 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!25 = !DILocation(line: 10, column: 3, scope: !7) +!26 = !DILocation(line: 10, column: 14, scope: !7) +!27 = !DILocation(line: 10, column: 20, scope: !7) +!28 = !{!29, !29, i64 0} +!29 = !{!"any pointer", !30, i64 0} +!30 = !{!"omnipotent char", !31, i64 0} +!31 = !{!"Simple C/C++ TBAA"} +!32 = !DILocation(line: 11, column: 40, scope: !7) +!33 = !DILocation(line: 11, column: 45, scope: !7) +!34 = !DILocation(line: 11, column: 10, scope: !7) +!35 = !DILocation(line: 12, column: 1, scope: !7) +!36 = !DILocation(line: 11, column: 3, scope: !7) +!37 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 8, type: !38, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !40) +!38 = !DISubroutineType(types: !39) +!39 = !{!21} +!40 = !{} diff --git a/llvm/test/CodeGen/SBF/CORE/anon-union-localvar-pragma.ll b/llvm/test/CodeGen/SBF/CORE/anon-union-localvar-pragma.ll new file mode 100644 index 00000000000000..9c6663bf8ce067 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/anon-union-localvar-pragma.ll @@ -0,0 +1,127 @@ +; RUN: opt -O2 -mtriple=sbf %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -o - %t1 | FileCheck %s +; +; Source: +; #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record) +; typedef union { +; struct { +; void *kernel; +; void *user; +; }; +; unsigned is_kernel : 1; +; } sockptr_t; +; #pragma clang attribute pop +; void *foo(void); +; int test() { +; sockptr_t *arg = foo(); +; return __builtin_preserve_field_info(arg->is_kernel, 1); +; } +; Compilation flag: +; clang -target bpf -O2 -S -emit-llvm -g -Xclang -disable-llvm-passes test.c + +%union.sockptr_t = type { %struct.anon } +%struct.anon = type { ptr, ptr } + +; Function Attrs: nounwind +define dso_local i32 @test() #0 !dbg !7 { +entry: + %arg = alloca ptr, align 8 + call void @llvm.lifetime.start.p0(i64 8, ptr %arg) #6, !dbg !25 + call void @llvm.dbg.declare(metadata ptr %arg, metadata !12, metadata !DIExpression()), !dbg !26 + %call = call ptr @foo(), !dbg !27 + store ptr %call, ptr %arg, align 8, !dbg !26, !tbaa !28 + %0 = load ptr, ptr %arg, align 8, !dbg !32, !tbaa !28 + %1 = call ptr @llvm.preserve.struct.access.index.p0.p0(ptr elementtype(%union.sockptr_t) %0, i32 0, i32 1), !dbg !33, !llvm.preserve.access.index !15 + %2 = call i32 @llvm.bpf.preserve.field.info.p0(ptr %1, i64 1), !dbg !34 + call void @llvm.lifetime.end.p0(i64 8, ptr %arg) #6, !dbg !35 + ret i32 %2, !dbg !36 +} + +; CHECK: .long 56 # BTF_KIND_TYPEDEF(id = 7) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 0 # BTF_KIND_UNION(id = 8) + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "sockptr_t" # string offset=56 +; CHECK: .ascii "0:1" # string offset=101 + + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp[[#]] +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 101 +; CHECK-NEXT: .long 1 + +; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn +declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +declare !dbg !37 dso_local ptr @foo() #3 + +; Function Attrs: nocallback nofree nosync nounwind readnone willreturn +declare ptr @llvm.preserve.struct.access.index.p0.p0(ptr, i32 immarg, i32 immarg) #4 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0(ptr, i64 immarg) #5 + +; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn +declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { argmemonly nocallback nofree nosync nounwind willreturn } +attributes #2 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #4 = { nocallback nofree nosync nounwind readnone willreturn } +attributes #5 = { nounwind readnone } +attributes #6 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 8c7d5118961e7ffc0304126ec2122d21e2eb1f79)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/test/anon", checksumkind: CSK_MD5, checksum: "2c5f698241a8b5ddf345a5743dfca258") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 7, !"frame-pointer", i32 2} +!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 8c7d5118961e7ffc0304126ec2122d21e2eb1f79)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 11, type: !8, scopeLine: 11, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DILocalVariable(name: "arg", scope: !7, file: !1, line: 12, type: !13) +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "sockptr_t", file: !1, line: 8, baseType: !15) +!15 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !1, line: 2, size: 128, elements: !16) +!16 = !{!17, !23} +!17 = !DIDerivedType(tag: DW_TAG_member, scope: !15, file: !1, line: 3, baseType: !18, size: 128) +!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !15, file: !1, line: 3, size: 128, elements: !19) +!19 = !{!20, !22} +!20 = !DIDerivedType(tag: DW_TAG_member, name: "kernel", scope: !18, file: !1, line: 4, baseType: !21, size: 64) +!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!22 = !DIDerivedType(tag: DW_TAG_member, name: "user", scope: !18, file: !1, line: 5, baseType: !21, size: 64, offset: 64) +!23 = !DIDerivedType(tag: DW_TAG_member, name: "is_kernel", scope: !15, file: !1, line: 7, baseType: !24, size: 1, flags: DIFlagBitField, extraData: i64 0) +!24 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!25 = !DILocation(line: 12, column: 3, scope: !7) +!26 = !DILocation(line: 12, column: 14, scope: !7) +!27 = !DILocation(line: 12, column: 20, scope: !7) +!28 = !{!29, !29, i64 0} +!29 = !{!"any pointer", !30, i64 0} +!30 = !{!"omnipotent char", !31, i64 0} +!31 = !{!"Simple C/C++ TBAA"} +!32 = !DILocation(line: 13, column: 40, scope: !7) +!33 = !DILocation(line: 13, column: 45, scope: !7) +!34 = !DILocation(line: 13, column: 10, scope: !7) +!35 = !DILocation(line: 14, column: 1, scope: !7) +!36 = !DILocation(line: 13, column: 3, scope: !7) +!37 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 10, type: !38, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !40) +!38 = !DISubroutineType(types: !39) +!39 = !{!21} +!40 = !{} diff --git a/llvm/test/CodeGen/SBF/CORE/btf-id-duplicate.ll b/llvm/test/CodeGen/SBF/CORE/btf-id-duplicate.ll new file mode 100644 index 00000000000000..c45449929e31da --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/btf-id-duplicate.ll @@ -0,0 +1,99 @@ +; RUN: opt -O2 -mtriple=sbf %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -o - %t1 | FileCheck %s +; RUN: opt -passes='default' -mtriple=sbf %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -o - %t1 | FileCheck %s +; +; Source: +; struct s1 { int a; int b; }; +; int foo(struct s1 *arg) { return __builtin_btf_type_id(*arg, 0); } +; int bar(struct s1 *arg) { return __builtin_btf_type_id(*arg, 0); } +; Compilation flag: +; clang -target bpf -O2 -S -emit-llvm -g -Xclang -disable-llvm-passes test.c + +%struct.s1 = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @foo(%struct.s1* %arg) #0 !dbg !7 { +entry: + %arg.addr = alloca %struct.s1*, align 8 + store %struct.s1* %arg, %struct.s1** %arg.addr, align 8, !tbaa !18 + call void @llvm.dbg.declare(metadata %struct.s1** %arg.addr, metadata !17, metadata !DIExpression()), !dbg !22 + %0 = call i64 @llvm.bpf.btf.type.id(i32 0, i64 0), !dbg !23, !llvm.preserve.access.index !12 + %conv = trunc i64 %0 to i32, !dbg !23 + ret i32 %conv, !dbg !24 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind readnone +declare i64 @llvm.bpf.btf.type.id(i32, i64) #2 + +; Function Attrs: nounwind +define dso_local i32 @bar(%struct.s1* %arg) #0 !dbg !25 { +entry: + %arg.addr = alloca %struct.s1*, align 8 + store %struct.s1* %arg, %struct.s1** %arg.addr, align 8, !tbaa !18 + call void @llvm.dbg.declare(metadata %struct.s1** %arg.addr, metadata !27, metadata !DIExpression()), !dbg !28 + %0 = call i64 @llvm.bpf.btf.type.id(i32 1, i64 0), !dbg !29, !llvm.preserve.access.index !12 + %conv = trunc i64 %0 to i32, !dbg !29 + ret i32 %conv, !dbg !30 +} + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 2) + +; CHECK: .ascii "s1" # string offset=1 +; CHECK: .ascii ".text" # string offset=20 +; CHECK: .byte 48 # string offset=26 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 20 # Field reloc section string offset=20 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 6 + +attributes #0 = { nounwind "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git c1c153c3c70641a23c4a9540a897ff2d4eb4c5b2)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/dup") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git c1c153c3c70641a23c4a9540a897ff2d4eb4c5b2)"} +!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !16) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 64, elements: !13) +!13 = !{!14, !15} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !12, file: !1, line: 1, baseType: !10, size: 32) +!15 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !12, file: !1, line: 1, baseType: !10, size: 32, offset: 32) +!16 = !{!17} +!17 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 2, type: !11) +!18 = !{!19, !19, i64 0} +!19 = !{!"any pointer", !20, i64 0} +!20 = !{!"omnipotent char", !21, i64 0} +!21 = !{!"Simple C/C++ TBAA"} +!22 = !DILocation(line: 2, column: 20, scope: !7) +!23 = !DILocation(line: 2, column: 34, scope: !7) +!24 = !DILocation(line: 2, column: 27, scope: !7) +!25 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !26) +!26 = !{!27} +!27 = !DILocalVariable(name: "arg", arg: 1, scope: !25, file: !1, line: 3, type: !11) +!28 = !DILocation(line: 3, column: 20, scope: !25) +!29 = !DILocation(line: 3, column: 34, scope: !25) +!30 = !DILocation(line: 3, column: 27, scope: !25) diff --git a/llvm/test/CodeGen/SBF/CORE/field-reloc-alu32.ll b/llvm/test/CodeGen/SBF/CORE/field-reloc-alu32.ll new file mode 100644 index 00000000000000..c39a7678dd04a5 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/field-reloc-alu32.ll @@ -0,0 +1,75 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct b { int d; int e; } c; +; int f() { +; return __builtin_preserve_field_info(c.e, 0); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.b = type { i32, i32 } + +@c = common dso_local global %struct.b zeroinitializer, align 4, !dbg !0 + +; Function Attrs: nounwind readnone +define dso_local i32 @f() local_unnamed_addr #0 !dbg !15 { +entry: + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.bs(%struct.b* elementtype(%struct.b) nonnull @c, i32 1, i32 1), !dbg !18, !llvm.preserve.access.index !6 + %1 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %0, i64 0), !dbg !19 + ret i32 %1, !dbg !20 +} + +; CHECK: mov64 r0, 4 +; CHECK: exit + +; CHECK: .long 13 # BTF_KIND_STRUCT(id = 4) + +; CHECK: .ascii ".text" # string offset=7 +; CHECK: .byte 98 # string offset=13 +; CHECK: .ascii "0:1" # string offset=19 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 7 # Field reloc section string offset=7 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 19 +; CHECK-NEXT: .long 0 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.bs(%struct.b*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "c", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git d5509db439a1bb3f0822c42398c8b5921a665478)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "b", file: !3, line: 1, size: 64, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !6, file: !3, line: 1, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "e", scope: !6, file: !3, line: 1, baseType: !9, size: 32, offset: 32) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git d5509db439a1bb3f0822c42398c8b5921a665478)"} +!15 = distinct !DISubprogram(name: "f", scope: !3, file: !3, line: 2, type: !16, scopeLine: 2, isDefinition: true, isOptimized: true, unit: !2, retainedNodes: !4) +!16 = !DISubroutineType(types: !17) +!17 = !{!9} +!18 = !DILocation(line: 3, column: 42, scope: !15) +!19 = !DILocation(line: 3, column: 10, scope: !15) +!20 = !DILocation(line: 3, column: 3, scope: !15) diff --git a/llvm/test/CodeGen/SBF/CORE/field-reloc-bitfield-1.ll b/llvm/test/CodeGen/SBF/CORE/field-reloc-bitfield-1.ll new file mode 100644 index 00000000000000..af61a51ca21198 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/field-reloc-bitfield-1.ll @@ -0,0 +1,126 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU32 %s +; Source code: +; struct s { +; unsigned long long f1; +; unsigned f2; +; unsigned f3; +; unsigned f4; +; unsigned char f5; +; unsigned bf1:5, +; bf2:1; +; }; +; enum {FIELD_TYPE_OFFSET = 0, FIELD_TYPE_SIZE = 1, FIELD_TYPE_LSHIFT_U64 = 4,}; +; int test(struct s *arg) { +; return __builtin_preserve_field_info(arg->bf2, FIELD_TYPE_OFFSET) + +; __builtin_preserve_field_info(arg->bf2, FIELD_TYPE_SIZE) + +; __builtin_preserve_field_info(arg->bf2, FIELD_TYPE_LSHIFT_U64); +; } +; Compilation flag: +; clang -target bpfel -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s = type { i64, i32, i32, i32, i8, i8 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%struct.s* %arg) local_unnamed_addr #0 !dbg !13 { +entry: + call void @llvm.dbg.value(metadata %struct.s* %arg, metadata !30, metadata !DIExpression()), !dbg !31 + %0 = tail call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.ss(%struct.s* elementtype(%struct.s) %arg, i32 5, i32 6), !dbg !32, !llvm.preserve.access.index !18 + %1 = tail call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %0, i64 0), !dbg !33 + %2 = tail call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %0, i64 1), !dbg !34 + %add = add i32 %2, %1, !dbg !35 + %3 = tail call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %0, i64 4), !dbg !36 + %add1 = add i32 %add, %3, !dbg !37 + ret i32 %add1, !dbg !38 +} + +; CHECK: mov64 r1, 20 +; CHECK: mov64 r0, 4 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK-EL: mov64 r1, 50 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 2) + +; CHECK: .byte 115 # string offset=1 +; CHECK: .ascii ".text" # string offset=89 +; CHECK: .ascii "0:6" # string offset=95 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 89 # Field reloc section string offset=89 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 95 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 95 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 95 +; CHECK-NEXT: .long 4 + +; Function Attrs: nounwind readnone +declare i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.ss(%struct.s*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i8(i8*, i64) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git bc6913e314806882e2b537b5b03996800078d2ad)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 10, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6, !7, !8} +!6 = !DIEnumerator(name: "FIELD_TYPE_OFFSET", value: 0, isUnsigned: true) +!7 = !DIEnumerator(name: "FIELD_TYPE_SIZE", value: 1, isUnsigned: true) +!8 = !DIEnumerator(name: "FIELD_TYPE_LSHIFT_U64", value: 4, isUnsigned: true) +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git bc6913e314806882e2b537b5b03996800078d2ad)"} +!13 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 11, type: !14, scopeLine: 11, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !29) +!14 = !DISubroutineType(types: !15) +!15 = !{!16, !17} +!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64) +!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 1, size: 192, elements: !19) +!19 = !{!20, !22, !23, !24, !25, !27, !28} +!20 = !DIDerivedType(tag: DW_TAG_member, name: "f1", scope: !18, file: !1, line: 2, baseType: !21, size: 64) +!21 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned) +!22 = !DIDerivedType(tag: DW_TAG_member, name: "f2", scope: !18, file: !1, line: 3, baseType: !4, size: 32, offset: 64) +!23 = !DIDerivedType(tag: DW_TAG_member, name: "f3", scope: !18, file: !1, line: 4, baseType: !4, size: 32, offset: 96) +!24 = !DIDerivedType(tag: DW_TAG_member, name: "f4", scope: !18, file: !1, line: 5, baseType: !4, size: 32, offset: 128) +!25 = !DIDerivedType(tag: DW_TAG_member, name: "f5", scope: !18, file: !1, line: 6, baseType: !26, size: 8, offset: 160) +!26 = !DIBasicType(name: "unsigned char", size: 8, encoding: DW_ATE_unsigned_char) +!27 = !DIDerivedType(tag: DW_TAG_member, name: "bf1", scope: !18, file: !1, line: 7, baseType: !4, size: 5, offset: 168, flags: DIFlagBitField, extraData: i64 168) +!28 = !DIDerivedType(tag: DW_TAG_member, name: "bf2", scope: !18, file: !1, line: 8, baseType: !4, size: 1, offset: 173, flags: DIFlagBitField, extraData: i64 168) +!29 = !{!30} +!30 = !DILocalVariable(name: "arg", arg: 1, scope: !13, file: !1, line: 11, type: !17) +!31 = !DILocation(line: 0, scope: !13) +!32 = !DILocation(line: 12, column: 45, scope: !13) +!33 = !DILocation(line: 12, column: 10, scope: !13) +!34 = !DILocation(line: 13, column: 10, scope: !13) +!35 = !DILocation(line: 12, column: 69, scope: !13) +!36 = !DILocation(line: 14, column: 10, scope: !13) +!37 = !DILocation(line: 13, column: 67, scope: !13) +!38 = !DILocation(line: 12, column: 3, scope: !13) diff --git a/llvm/test/CodeGen/SBF/CORE/field-reloc-bitfield-2.ll b/llvm/test/CodeGen/SBF/CORE/field-reloc-bitfield-2.ll new file mode 100644 index 00000000000000..78354493464a45 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/field-reloc-bitfield-2.ll @@ -0,0 +1,124 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU32 %s +; Source code: +; struct s { +; char f1; +; char bf1:6, +; bf2:2, +; bf3:5, +; bf4:3; +; }; +; enum {FIELD_TYPE_OFFSET = 0, FIELD_TYPE_SIZE = 1, FIELD_TYPE_LSHIFT_U64 = 4,}; +; int test(struct s *arg) { +; return __builtin_preserve_field_info(arg->bf4, FIELD_TYPE_OFFSET) + +; __builtin_preserve_field_info(arg->bf4, FIELD_TYPE_SIZE) + +; __builtin_preserve_field_info(arg->bf4, FIELD_TYPE_LSHIFT_U64); +; } +; For this case, the IR type has the same starting storage offset for fields +; bf1, bf1, bf3 and bf4 and the ABI alignment is 1 byte. So for bf4 access, +; the starting offset has to be at the beginning of field bf3. +; Compilation flag: +; clang -target bpfel -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s = type <{ i8, i16 }> + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%struct.s* %arg) local_unnamed_addr #0 !dbg !13 { +entry: + call void @llvm.dbg.value(metadata %struct.s* %arg, metadata !27, metadata !DIExpression()), !dbg !28 + %0 = tail call i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.ss(%struct.s* elementtype(%struct.s) %arg, i32 1, i32 4), !dbg !29, !llvm.preserve.access.index !18 + %1 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %0, i64 0), !dbg !30 + %2 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %0, i64 1), !dbg !31 + %add = add i32 %2, %1, !dbg !32 + %3 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %0, i64 4), !dbg !33 + %add1 = add i32 %add, %3, !dbg !34 + ret i32 %add1, !dbg !35 +} + +; CHECK: mov64 r1, 2 +; CHECK: mov64 r0, 1 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK-EL: mov64 r1, 56 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 2) + +; CHECK: .byte 115 # string offset=1 +; CHECK: .ascii ".text" # string offset=40 +; CHECK: .ascii "0:4" # string offset=46 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 40 # Field reloc section string offset=40 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 46 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 46 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 46 +; CHECK-NEXT: .long 4 + +; Function Attrs: nounwind readnone +declare i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.ss(%struct.s*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i16(i16*, i64) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 630ca91834ecc06349cb3b4bd2982c1b85b5ad96)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 8, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6, !7, !8} +!6 = !DIEnumerator(name: "FIELD_TYPE_OFFSET", value: 0, isUnsigned: true) +!7 = !DIEnumerator(name: "FIELD_TYPE_SIZE", value: 1, isUnsigned: true) +!8 = !DIEnumerator(name: "FIELD_TYPE_LSHIFT_U64", value: 4, isUnsigned: true) +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 630ca91834ecc06349cb3b4bd2982c1b85b5ad96)"} +!13 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 9, type: !14, scopeLine: 9, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !26) +!14 = !DISubroutineType(types: !15) +!15 = !{!16, !17} +!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64) +!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 1, size: 24, elements: !19) +!19 = !{!20, !22, !23, !24, !25} +!20 = !DIDerivedType(tag: DW_TAG_member, name: "f1", scope: !18, file: !1, line: 2, baseType: !21, size: 8) +!21 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!22 = !DIDerivedType(tag: DW_TAG_member, name: "bf1", scope: !18, file: !1, line: 3, baseType: !21, size: 6, offset: 8, flags: DIFlagBitField, extraData: i64 8) +!23 = !DIDerivedType(tag: DW_TAG_member, name: "bf2", scope: !18, file: !1, line: 4, baseType: !21, size: 2, offset: 14, flags: DIFlagBitField, extraData: i64 8) +!24 = !DIDerivedType(tag: DW_TAG_member, name: "bf3", scope: !18, file: !1, line: 5, baseType: !21, size: 5, offset: 16, flags: DIFlagBitField, extraData: i64 8) +!25 = !DIDerivedType(tag: DW_TAG_member, name: "bf4", scope: !18, file: !1, line: 6, baseType: !21, size: 3, offset: 21, flags: DIFlagBitField, extraData: i64 8) +!26 = !{!27} +!27 = !DILocalVariable(name: "arg", arg: 1, scope: !13, file: !1, line: 9, type: !17) +!28 = !DILocation(line: 0, scope: !13) +!29 = !DILocation(line: 10, column: 45, scope: !13) +!30 = !DILocation(line: 10, column: 10, scope: !13) +!31 = !DILocation(line: 11, column: 10, scope: !13) +!32 = !DILocation(line: 10, column: 69, scope: !13) +!33 = !DILocation(line: 12, column: 10, scope: !13) +!34 = !DILocation(line: 11, column: 67, scope: !13) +!35 = !DILocation(line: 10, column: 3, scope: !13) diff --git a/llvm/test/CodeGen/SBF/CORE/field-reloc-bitfield-record-align16.ll b/llvm/test/CodeGen/SBF/CORE/field-reloc-bitfield-record-align16.ll new file mode 100644 index 00000000000000..a32df0da09b0b4 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/field-reloc-bitfield-record-align16.ll @@ -0,0 +1,105 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; Source code: +; struct t2 { +; int a[8]; +; long: 64; +; long: 64; +; long: 64; +; long: 64; +; }; +; +; struct t1 { +; int f1: 1; +; int f2: 2; +; long: 61; +; long: 64; +; long: 64; +; long: 64; +; long: 64; +; long: 64; +; long: 64; +; long: 64; +; struct t2 f3; +; } __attribute__((preserve_access_index)); +; +; struct t1 g; +; int foo() { +; return g.f1; +; } +; Compilation flag: +; clang -target bpfel -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +; ModuleID = 'test.c' +source_filename = "test.c" +target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" +target triple = "sbf" + +%struct.t1 = type { i512, %struct.t2 } +%struct.t2 = type { [8 x i32], i256 } + +@g = dso_local global %struct.t1 zeroinitializer, align 4, !dbg !0 + +; Function Attrs: nounwind +define dso_local i32 @foo() #0 !dbg !22 { +entry: + %0 = call i512* @llvm.preserve.struct.access.index.p0i512.p0s_struct.t1s(%struct.t1* elementtype(%struct.t1) @g, i32 0, i32 0), !dbg !26, !llvm.preserve.access.index !5 + %bf.load = load i512, i512* %0, align 4, !dbg !26 + %bf.shl = shl i512 %bf.load, 511, !dbg !26 + %bf.ashr = ashr i512 %bf.shl, 511, !dbg !26 + %bf.cast = trunc i512 %bf.ashr to i32, !dbg !26 + ret i32 %bf.cast, !dbg !27 +} + +; CHECK: .long 68 # BTF_KIND_STRUCT(id = 4) + +; CHECK: .ascii ".text" # string offset=9 +; CHECK: .ascii "t1" # string offset=68 +; CHECK: .ascii "0:0" # string offset=105 + +; CHECK: .long 16 # FieldReloc +; CHECK: .long 9 # Field reloc section string offset=9 +; CHECK: .long 1 +; CHECK: .long .Ltmp[[#]] +; CHECK: .long 4 +; CHECK: .long 105 +; CHECK: .long 0 + +; Function Attrs: nofree nosync nounwind readnone willreturn +declare i512* @llvm.preserve.struct.access.index.p0i512.p0s_struct.t1s(%struct.t1*, i32 immarg, i32 immarg) #1 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { nofree nosync nounwind readnone willreturn } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!17, !18, !19, !20} +!llvm.ident = !{!21} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 23, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 468279d2d249e44ffa3535a613245b4ceb81a908)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/bitfield/simple", checksumkind: CSK_MD5, checksum: "b9c80125731b87136772eec36d0b48a3") +!4 = !{!0} +!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 9, size: 1024, elements: !6) +!6 = !{!7, !9, !10} +!7 = !DIDerivedType(tag: DW_TAG_member, name: "f1", scope: !5, file: !3, line: 10, baseType: !8, size: 1, flags: DIFlagBitField, extraData: i64 0) +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!9 = !DIDerivedType(tag: DW_TAG_member, name: "f2", scope: !5, file: !3, line: 11, baseType: !8, size: 2, offset: 1, flags: DIFlagBitField, extraData: i64 0) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "f3", scope: !5, file: !3, line: 20, baseType: !11, size: 512, offset: 512) +!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", file: !3, line: 1, size: 512, elements: !12) +!12 = !{!13} +!13 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !11, file: !3, line: 2, baseType: !14, size: 256) +!14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !8, size: 256, elements: !15) +!15 = !{!16} +!16 = !DISubrange(count: 8) +!17 = !{i32 7, !"Dwarf Version", i32 5} +!18 = !{i32 2, !"Debug Info Version", i32 3} +!19 = !{i32 1, !"wchar_size", i32 4} +!20 = !{i32 7, !"frame-pointer", i32 2} +!21 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 468279d2d249e44ffa3535a613245b4ceb81a908)"} +!22 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 24, type: !23, scopeLine: 24, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !25) +!23 = !DISubroutineType(types: !24) +!24 = !{!8} +!25 = !{} +!26 = !DILocation(line: 25, column: 12, scope: !22) +!27 = !DILocation(line: 25, column: 3, scope: !22) diff --git a/llvm/test/CodeGen/SBF/CORE/field-reloc-duplicate.ll b/llvm/test/CodeGen/SBF/CORE/field-reloc-duplicate.ll new file mode 100644 index 00000000000000..f3b85d7666c168 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/field-reloc-duplicate.ll @@ -0,0 +1,106 @@ +; RUN: opt -O2 -mtriple=sbf %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -o - %t1 | FileCheck %s +; RUN: opt -passes='default' -mtriple=sbf %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -o - %t1 | FileCheck %s +; +; Source: +; struct s1 { int a; int b; } __attribute__((preserve_access_index)); +; int foo(struct s1 *arg) { return arg->a; } +; int bar(struct s1 *arg) { return arg->a; } +; Compilation flag: +; clang -target bpf -O2 -S -emit-llvm -g -Xclang -disable-llvm-passes test.c + +%struct.s1 = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @foo(%struct.s1* %arg) #0 !dbg !7 { +entry: + %arg.addr = alloca %struct.s1*, align 8 + store %struct.s1* %arg, %struct.s1** %arg.addr, align 8, !tbaa !18 + call void @llvm.dbg.declare(metadata %struct.s1** %arg.addr, metadata !17, metadata !DIExpression()), !dbg !22 + %0 = load %struct.s1*, %struct.s1** %arg.addr, align 8, !dbg !23, !tbaa !18 + %1 = call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %0, i32 0, i32 0), !dbg !24, !llvm.preserve.access.index !12 + %2 = load i32, i32* %1, align 4, !dbg !24, !tbaa !25 + ret i32 %2, !dbg !28 +} + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind +define dso_local i32 @bar(%struct.s1* %arg) #0 !dbg !29 { +entry: + %arg.addr = alloca %struct.s1*, align 8 + store %struct.s1* %arg, %struct.s1** %arg.addr, align 8, !tbaa !18 + call void @llvm.dbg.declare(metadata %struct.s1** %arg.addr, metadata !31, metadata !DIExpression()), !dbg !32 + %0 = load %struct.s1*, %struct.s1** %arg.addr, align 8, !dbg !33, !tbaa !18 + %1 = call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %0, i32 0, i32 0), !dbg !34, !llvm.preserve.access.index !12 + %2 = load i32, i32* %1, align 4, !dbg !34, !tbaa !25 + ret i32 %2, !dbg !35 +} + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 2) + +; CHECK: .ascii "s1" # string offset=1 +; CHECK: .ascii ".text" # string offset=20 +; CHECK: .ascii "0:0" # string offset=26 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 20 # Field reloc section string offset=20 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 0 + +attributes #0 = { nounwind "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable willreturn } +attributes #2 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git 2f40e20613758b3e11a15494c09f4b6973673d6b)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git 2f40e20613758b3e11a15494c09f4b6973673d6b)"} +!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !16) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 64, elements: !13) +!13 = !{!14, !15} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !12, file: !1, line: 1, baseType: !10, size: 32) +!15 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !12, file: !1, line: 1, baseType: !10, size: 32, offset: 32) +!16 = !{!17} +!17 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 2, type: !11) +!18 = !{!19, !19, i64 0} +!19 = !{!"any pointer", !20, i64 0} +!20 = !{!"omnipotent char", !21, i64 0} +!21 = !{!"Simple C/C++ TBAA"} +!22 = !DILocation(line: 2, column: 20, scope: !7) +!23 = !DILocation(line: 2, column: 34, scope: !7) +!24 = !DILocation(line: 2, column: 39, scope: !7) +!25 = !{!26, !27, i64 0} +!26 = !{!"s1", !27, i64 0, !27, i64 4} +!27 = !{!"int", !20, i64 0} +!28 = !DILocation(line: 2, column: 27, scope: !7) +!29 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !30) +!30 = !{!31} +!31 = !DILocalVariable(name: "arg", arg: 1, scope: !29, file: !1, line: 3, type: !11) +!32 = !DILocation(line: 3, column: 20, scope: !29) +!33 = !DILocation(line: 3, column: 34, scope: !29) +!34 = !DILocation(line: 3, column: 39, scope: !29) +!35 = !DILocation(line: 3, column: 27, scope: !29) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-array-2.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-array-2.ll new file mode 100644 index 00000000000000..4756ae5dc097ee --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-array-2.ll @@ -0,0 +1,84 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s + +; Source: +; enum { FIELD_EXISTENCE = 2, }; +; struct s1 { int a1; }; +; int test() { +; struct s1 *v = 0; +; return __builtin_preserve_field_info(v[0], FIELD_EXISTENCE); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s1 = type { i32 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test() local_unnamed_addr #0 !dbg !17 { +entry: + call void @llvm.dbg.value(metadata %struct.s1* null, metadata !21, metadata !DIExpression()), !dbg !22 + %0 = tail call %struct.s1* @llvm.preserve.array.access.index.p0s_struct.s1s.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) null, i32 0, i32 0), !dbg !23, !llvm.preserve.access.index !8 + %1 = tail call i32 @llvm.bpf.preserve.field.info.p0s_struct.s1s(%struct.s1* %0, i64 2), !dbg !24 + ret i32 %1, !dbg !25 +} + +; CHECK: .long 16 # BTF_KIND_STRUCT(id = 4) + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "s1" # string offset=16 +; CHECK: .byte 48 # string offset=22 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 22 +; CHECK-NEXT: .long 2 + +; Function Attrs: nounwind readnone +declare %struct.s1* @llvm.preserve.array.access.index.p0s_struct.s1s.p0s_struct.s1s(%struct.s1*, i32 immarg, i32 immarg) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0s_struct.s1s(%struct.s1*, i64 immarg) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!13, !14, !15} +!llvm.ident = !{!16} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 32791937d7aceb0a5e1eaabf1bb1a6dbe1639792)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !7, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 1, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_EXISTENCE", value: 2, isUnsigned: true) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64) +!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 2, size: 32, elements: !10) +!10 = !{!11} +!11 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !9, file: !1, line: 2, baseType: !12, size: 32) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !{i32 7, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{i32 1, !"wchar_size", i32 4} +!16 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 32791937d7aceb0a5e1eaabf1bb1a6dbe1639792)"} +!17 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !18, scopeLine: 3, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !20) +!18 = !DISubroutineType(types: !19) +!19 = !{!12} +!20 = !{!21} +!21 = !DILocalVariable(name: "v", scope: !17, file: !1, line: 4, type: !8) +!22 = !DILocation(line: 0, scope: !17) +!23 = !DILocation(line: 5, column: 40, scope: !17) +!24 = !DILocation(line: 5, column: 10, scope: !17) +!25 = !DILocation(line: 5, column: 3, scope: !17) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-array.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-array.ll new file mode 100644 index 00000000000000..bda5d106f50d56 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-array.ll @@ -0,0 +1,87 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -filetype=asm -opaque-pointers -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -opaque-pointers -o - %t1 | FileCheck %s +; +; Source code: +; #define _(x) (__builtin_preserve_access_index(x)) +; struct s { int a; int b; }; +; int get_value(const void *addr); +; int test(struct s *arg) { return get_value(_(&arg[2].b)); } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.s* %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.s* %arg, metadata !17, metadata !DIExpression()), !dbg !18 + %0 = tail call %struct.s* @llvm.preserve.array.access.index.p0s_struct.ss.p0s_struct.ss(%struct.s* elementtype(%struct.s) %arg, i32 0, i32 2), !dbg !19, !llvm.preserve.access.index !11 + %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s* elementtype(%struct.s) %0, i32 1, i32 1), !dbg !19, !llvm.preserve.access.index !12 + %2 = bitcast i32* %1 to i8*, !dbg !19 + %call = tail call i32 @get_value(i8* %2) #4, !dbg !20 + ret i32 %call, !dbg !21 +} +; CHECK-LABEL: test +; CHECK: [[RELOC:.Ltmp[0-9]+]] +; CHECK: mov64 r2, 20 +; CHECK: add64 r1, r2 +; CHECK: call get_value +; CHECK: exit +; +; CHECK: .section .BTF.ext,"",@progbits +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 20 # Field reloc section string offset=20 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long [[RELOC]] +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i8*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare %struct.s* @llvm.preserve.array.access.index.p0s_struct.ss.p0s_struct.ss(%struct.s*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 (trunk 365789)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 9.0.0 (trunk 365789)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !8, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !16) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 2, size: 64, elements: !13) +!13 = !{!14, !15} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !12, file: !1, line: 2, baseType: !10, size: 32) +!15 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !12, file: !1, line: 2, baseType: !10, size: 32, offset: 32) +!16 = !{!17} +!17 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 4, type: !11) +!18 = !DILocation(line: 0, scope: !7) +!19 = !DILocation(line: 4, column: 44, scope: !7) +!20 = !DILocation(line: 4, column: 34, scope: !7) +!21 = !DILocation(line: 4, column: 27, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-1.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-1.ll new file mode 100644 index 00000000000000..896b3bdfaad706 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-1.ll @@ -0,0 +1,154 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; typedef struct s1 { int a1:7; int a2:4; int a3:5; int a4:16;} __s1; +; union u1 { int b1; __s1 b2; }; +; enum { FIELD_BYTE_SIZE = 1, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2.a1, FIELD_BYTE_SIZE); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a2, FIELD_BYTE_SIZE); +; unsigned r3 = __builtin_preserve_field_info(arg->b2.a3, FIELD_BYTE_SIZE); +; unsigned r4 = __builtin_preserve_field_info(arg->b2.a4, FIELD_BYTE_SIZE); +; /* r1: 4, r2: 4, r3: 4, r4: 4 */ +; return r1 + r2 + r3 + r4; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { i32 } +%struct.s1 = type { i32 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !11 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !28, metadata !DIExpression()), !dbg !33 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !34, !llvm.preserve.access.index !16 + %b2 = bitcast %union.u1* %0 to %struct.s1*, !dbg !34 + %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !35, !llvm.preserve.access.index !21 + %2 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %1, i64 1), !dbg !36 + call void @llvm.dbg.value(metadata i32 %2, metadata !29, metadata !DIExpression()), !dbg !33 + %3 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 1), !dbg !37, !llvm.preserve.access.index !21 + %4 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %3, i64 1), !dbg !38 + call void @llvm.dbg.value(metadata i32 %4, metadata !30, metadata !DIExpression()), !dbg !33 + %5 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 2), !dbg !39, !llvm.preserve.access.index !21 + %6 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %5, i64 1), !dbg !40 + call void @llvm.dbg.value(metadata i32 %6, metadata !31, metadata !DIExpression()), !dbg !33 + %7 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 3), !dbg !41, !llvm.preserve.access.index !21 + %8 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %7, i64 1), !dbg !42 + call void @llvm.dbg.value(metadata i32 %8, metadata !32, metadata !DIExpression()), !dbg !33 + %add = add i32 %4, %2, !dbg !43 + %add4 = add i32 %add, %6, !dbg !44 + %add5 = add i32 %add4, %8, !dbg !45 + ret i32 %add5, !dbg !46 +} + +; CHECK: mov64 r1, 4 +; CHECK: mov64 r0, 4 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: mov64 r1, 4 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: mov64 r1, 4 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=43 +; CHECK: .ascii "0:1:0" # string offset=49 +; CHECK: .ascii "0:1:1" # string offset=92 +; CHECK: .ascii "0:1:2" # string offset=98 +; CHECK: .ascii "0:1:3" # string offset=104 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 43 # Field reloc section string offset=43 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 49 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 92 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 98 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 104 +; CHECK-NEXT: .long 1 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 3, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_BYTE_SIZE", value: 1, isUnsigned: true) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)"} +!11 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !27) +!12 = !DISubroutineType(types: !13) +!13 = !{!14, !15} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 2, size: 32, elements: !17) +!17 = !{!18, !19} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !16, file: !1, line: 2, baseType: !14, size: 32) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !16, file: !1, line: 2, baseType: !20, size: 32) +!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s1", file: !1, line: 1, baseType: !21) +!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 32, elements: !22) +!22 = !{!23, !24, !25, !26} +!23 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !21, file: !1, line: 1, baseType: !14, size: 7, flags: DIFlagBitField, extraData: i64 0) +!24 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !21, file: !1, line: 1, baseType: !14, size: 4, offset: 7, flags: DIFlagBitField, extraData: i64 0) +!25 = !DIDerivedType(tag: DW_TAG_member, name: "a3", scope: !21, file: !1, line: 1, baseType: !14, size: 5, offset: 11, flags: DIFlagBitField, extraData: i64 0) +!26 = !DIDerivedType(tag: DW_TAG_member, name: "a4", scope: !21, file: !1, line: 1, baseType: !14, size: 16, offset: 16, flags: DIFlagBitField, extraData: i64 0) +!27 = !{!28, !29, !30, !31, !32} +!28 = !DILocalVariable(name: "arg", arg: 1, scope: !11, file: !1, line: 4, type: !15) +!29 = !DILocalVariable(name: "r1", scope: !11, file: !1, line: 5, type: !4) +!30 = !DILocalVariable(name: "r2", scope: !11, file: !1, line: 6, type: !4) +!31 = !DILocalVariable(name: "r3", scope: !11, file: !1, line: 7, type: !4) +!32 = !DILocalVariable(name: "r4", scope: !11, file: !1, line: 8, type: !4) +!33 = !DILocation(line: 0, scope: !11) +!34 = !DILocation(line: 5, column: 52, scope: !11) +!35 = !DILocation(line: 5, column: 55, scope: !11) +!36 = !DILocation(line: 5, column: 17, scope: !11) +!37 = !DILocation(line: 6, column: 55, scope: !11) +!38 = !DILocation(line: 6, column: 17, scope: !11) +!39 = !DILocation(line: 7, column: 55, scope: !11) +!40 = !DILocation(line: 7, column: 17, scope: !11) +!41 = !DILocation(line: 8, column: 55, scope: !11) +!42 = !DILocation(line: 8, column: 17, scope: !11) +!43 = !DILocation(line: 10, column: 13, scope: !11) +!44 = !DILocation(line: 10, column: 18, scope: !11) +!45 = !DILocation(line: 10, column: 23, scope: !11) +!46 = !DILocation(line: 10, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-2.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-2.ll new file mode 100644 index 00000000000000..4bb7dfe9145956 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-2.ll @@ -0,0 +1,143 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; typedef struct s1 { int a1; char a2; } __s1; +; union u1 { int b1; __s1 b2; }; +; enum { FIELD_BYTE_SIZE = 1, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2, FIELD_BYTE_SIZE); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a1, FIELD_BYTE_SIZE); +; unsigned r3 = __builtin_preserve_field_info(arg->b2.a2, FIELD_BYTE_SIZE); +; /* r1: 8, r2: 4, r3: 1 */ +; return r1 + r2 + r3; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { %struct.s1 } +%struct.s1 = type { i32, i8 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !11 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !27, metadata !DIExpression()), !dbg !31 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !32, !llvm.preserve.access.index !16 + %b2 = getelementptr inbounds %union.u1, %union.u1* %0, i64 0, i32 0, !dbg !32 + %1 = tail call i32 @llvm.bpf.preserve.field.info.p0s_struct.s1s(%struct.s1* %b2, i64 1), !dbg !33 + call void @llvm.dbg.value(metadata i32 %1, metadata !28, metadata !DIExpression()), !dbg !31 + %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !34, !llvm.preserve.access.index !21 + %3 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %2, i64 1), !dbg !35 + call void @llvm.dbg.value(metadata i32 %3, metadata !29, metadata !DIExpression()), !dbg !31 + %4 = tail call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 1, i32 1), !dbg !36, !llvm.preserve.access.index !21 + %5 = tail call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %4, i64 1), !dbg !37 + call void @llvm.dbg.value(metadata i32 %5, metadata !30, metadata !DIExpression()), !dbg !31 + %add = add i32 %3, %1, !dbg !38 + %add3 = add i32 %add, %5, !dbg !39 + ret i32 %add3, !dbg !40 +} + +; CHECK: mov64 r1, 8 +; CHECK: mov64 r0, 4 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: mov64 r1, 1 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=42 +; CHECK: .ascii "0:1" # string offset=48 +; CHECK: .ascii "0:1:0" # string offset=89 +; CHECK: .ascii "0:1:1" # string offset=95 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 42 # Field reloc section string offset=42 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 89 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 95 +; CHECK-NEXT: .long 1 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0s_struct.s1s(%struct.s1*, i64) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone +declare i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i8(i8*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 3, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_BYTE_SIZE", value: 1, isUnsigned: true) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)"} +!11 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !26) +!12 = !DISubroutineType(types: !13) +!13 = !{!14, !15} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 2, size: 64, elements: !17) +!17 = !{!18, !19} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !16, file: !1, line: 2, baseType: !14, size: 32) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !16, file: !1, line: 2, baseType: !20, size: 64) +!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s1", file: !1, line: 1, baseType: !21) +!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 64, elements: !22) +!22 = !{!23, !24} +!23 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !21, file: !1, line: 1, baseType: !14, size: 32) +!24 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !21, file: !1, line: 1, baseType: !25, size: 8, offset: 32) +!25 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!26 = !{!27, !28, !29, !30} +!27 = !DILocalVariable(name: "arg", arg: 1, scope: !11, file: !1, line: 4, type: !15) +!28 = !DILocalVariable(name: "r1", scope: !11, file: !1, line: 5, type: !4) +!29 = !DILocalVariable(name: "r2", scope: !11, file: !1, line: 6, type: !4) +!30 = !DILocalVariable(name: "r3", scope: !11, file: !1, line: 7, type: !4) +!31 = !DILocation(line: 0, scope: !11) +!32 = !DILocation(line: 5, column: 52, scope: !11) +!33 = !DILocation(line: 5, column: 17, scope: !11) +!34 = !DILocation(line: 6, column: 55, scope: !11) +!35 = !DILocation(line: 6, column: 17, scope: !11) +!36 = !DILocation(line: 7, column: 55, scope: !11) +!37 = !DILocation(line: 7, column: 17, scope: !11) +!38 = !DILocation(line: 9, column: 13, scope: !11) +!39 = !DILocation(line: 9, column: 18, scope: !11) +!40 = !DILocation(line: 9, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-3.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-3.ll new file mode 100644 index 00000000000000..c624fd25476152 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-3.ll @@ -0,0 +1,134 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; typedef struct s1 { int a1[10][10]; } __s1; +; union u1 { int b1; __s1 b2; }; +; enum { FIELD_BYTE_SIZE = 1, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2.a1[5], FIELD_BYTE_SIZE); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a1[5][5], FIELD_BYTE_SIZE); +; /* r1: 40, r2: 4 */ +; return r1 + r2; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { %struct.s1 } +%struct.s1 = type { [10 x [10 x i32]] } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !18 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !31, metadata !DIExpression()), !dbg !34 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !35, !llvm.preserve.access.index !22 + %b2 = getelementptr inbounds %union.u1, %union.u1* %0, i64 0, i32 0, !dbg !35 + %1 = tail call [10 x [10 x i32]]* @llvm.preserve.struct.access.index.p0a10a10i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !36, !llvm.preserve.access.index !27 + %2 = tail call [10 x i32]* @llvm.preserve.array.access.index.p0a10i32.p0a10a10i32([10 x [10 x i32]]* elementtype([10 x [10 x i32]]) %1, i32 1, i32 5), !dbg !37, !llvm.preserve.access.index !8 + %3 = tail call i32 @llvm.bpf.preserve.field.info.p0a10i32([10 x i32]* %2, i64 1), !dbg !38 + call void @llvm.dbg.value(metadata i32 %3, metadata !32, metadata !DIExpression()), !dbg !34 + %4 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a10i32([10 x i32]* elementtype([10 x i32]) %2, i32 1, i32 5), !dbg !39, !llvm.preserve.access.index !12 + %5 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %4, i64 1), !dbg !40 + call void @llvm.dbg.value(metadata i32 %5, metadata !33, metadata !DIExpression()), !dbg !34 + %add = add i32 %5, %3, !dbg !41 + ret i32 %add, !dbg !42 +} + +; CHECK: mov64 r1, 40 +; CHECK: mov64 r0, 4 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=54 +; CHECK: .ascii "0:1:0:5" # string offset=60 +; CHECK: .ascii "0:1:0:5:5" # string offset=105 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 54 # Field reloc section string offset=54 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 60 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 105 +; CHECK-NEXT: .long 1 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare [10 x [10 x i32]]* @llvm.preserve.struct.access.index.p0a10a10i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare [10 x i32]* @llvm.preserve.array.access.index.p0a10i32.p0a10a10i32([10 x [10 x i32]]*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0a10i32([10 x i32]*, i64) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.array.access.index.p0i32.p0a10i32([10 x i32]*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!14, !15, !16} +!llvm.ident = !{!17} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git c1e02f16f1105ffaf1c35ee8bc38b7d6db5c6ea9)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !7, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 3, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_BYTE_SIZE", value: 1, isUnsigned: true) +!7 = !{!8, !12} +!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 3200, elements: !10) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !{!11, !11} +!11 = !DISubrange(count: 10) +!12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 320, elements: !13) +!13 = !{!11} +!14 = !{i32 2, !"Dwarf Version", i32 4} +!15 = !{i32 2, !"Debug Info Version", i32 3} +!16 = !{i32 1, !"wchar_size", i32 4} +!17 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git c1e02f16f1105ffaf1c35ee8bc38b7d6db5c6ea9)"} +!18 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !19, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !30) +!19 = !DISubroutineType(types: !20) +!20 = !{!9, !21} +!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !22, size: 64) +!22 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 2, size: 3200, elements: !23) +!23 = !{!24, !25} +!24 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !22, file: !1, line: 2, baseType: !9, size: 32) +!25 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !22, file: !1, line: 2, baseType: !26, size: 3200) +!26 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s1", file: !1, line: 1, baseType: !27) +!27 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 3200, elements: !28) +!28 = !{!29} +!29 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !27, file: !1, line: 1, baseType: !8, size: 3200) +!30 = !{!31, !32, !33} +!31 = !DILocalVariable(name: "arg", arg: 1, scope: !18, file: !1, line: 4, type: !21) +!32 = !DILocalVariable(name: "r1", scope: !18, file: !1, line: 5, type: !4) +!33 = !DILocalVariable(name: "r2", scope: !18, file: !1, line: 6, type: !4) +!34 = !DILocation(line: 0, scope: !18) +!35 = !DILocation(line: 5, column: 52, scope: !18) +!36 = !DILocation(line: 5, column: 55, scope: !18) +!37 = !DILocation(line: 5, column: 47, scope: !18) +!38 = !DILocation(line: 5, column: 17, scope: !18) +!39 = !DILocation(line: 6, column: 47, scope: !18) +!40 = !DILocation(line: 6, column: 17, scope: !18) +!41 = !DILocation(line: 8, column: 13, scope: !18) +!42 = !DILocation(line: 8, column: 3, scope: !18) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-4.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-4.ll new file mode 100644 index 00000000000000..6bc6e184d11246 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-byte-size-4.ll @@ -0,0 +1,87 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; typedef struct s1 { int a1; int a2:4; int a3;} __s1; +; enum { FIELD_BYTE_SIZE = 1, }; +; int test(__s1 *arg) { +; return __builtin_preserve_field_info(arg->a2, FIELD_BYTE_SIZE); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s1 = type { i32, i8, i32 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%struct.s1* readnone %arg) local_unnamed_addr #0 !dbg !11 { +entry: + call void @llvm.dbg.value(metadata %struct.s1* %arg, metadata !23, metadata !DIExpression()), !dbg !24 + %0 = tail call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %arg, i32 1, i32 1), !dbg !25, !llvm.preserve.access.index !17 + %1 = tail call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %0, i64 1), !dbg !26 + ret i32 %1, !dbg !27 +} + +; CHECK: mov64 r0, 4 +; CHECK: exit + +; CHECK: .long 6 # BTF_KIND_STRUCT(id = 3) + +; CHECK: .ascii "s1" # string offset=6 +; CHECK: .ascii ".text" # string offset=31 +; CHECK: .ascii "0:1" # string offset=37 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 31 # Field reloc section string offset=31 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 37 +; CHECK-NEXT: .long 1 + +; Function Attrs: nounwind readnone +declare i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i8(i8*, i64) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 6c63b5d6a1cb84a75807804337c855a41c976260)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 2, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_BYTE_SIZE", value: 1, isUnsigned: true) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 6c63b5d6a1cb84a75807804337c855a41c976260)"} +!11 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !12, scopeLine: 3, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !22) +!12 = !DISubroutineType(types: !13) +!13 = !{!14, !15} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s1", file: !1, line: 1, baseType: !17) +!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 96, elements: !18) +!18 = !{!19, !20, !21} +!19 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !17, file: !1, line: 1, baseType: !14, size: 32) +!20 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !17, file: !1, line: 1, baseType: !14, size: 4, offset: 32, flags: DIFlagBitField, extraData: i64 32) +!21 = !DIDerivedType(tag: DW_TAG_member, name: "a3", scope: !17, file: !1, line: 1, baseType: !14, size: 32, offset: 64) +!22 = !{!23} +!23 = !DILocalVariable(name: "arg", arg: 1, scope: !11, file: !1, line: 3, type: !15) +!24 = !DILocation(line: 0, scope: !11) +!25 = !DILocation(line: 4, column: 45, scope: !11) +!26 = !DILocation(line: 4, column: 10, scope: !11) +!27 = !DILocation(line: 4, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-1.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-1.ll new file mode 100644 index 00000000000000..84a347eff56263 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-1.ll @@ -0,0 +1,168 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; typedef unsigned __uint; +; struct s1 { int a1; __uint a2:9; __uint a3:4; }; +; union u1 { int b1; __uint b2:9; __uint b3:4; }; +; enum { FIELD_EXISTENCE = 2, }; +; int test(struct s1 *arg1, union u1 *arg2) { +; unsigned r1 = __builtin_preserve_field_info(arg1->a1, FIELD_EXISTENCE); +; unsigned r2 = __builtin_preserve_field_info(arg1->a3, FIELD_EXISTENCE); +; unsigned r3 = __builtin_preserve_field_info(arg2->b1, FIELD_EXISTENCE); +; unsigned r4 = __builtin_preserve_field_info(arg2->b3, FIELD_EXISTENCE); +; return r1 + r2 + r3 + r4; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s1 = type { i32, i16 } +%union.u1 = type { i32 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%struct.s1* %arg1, %union.u1* %arg2) local_unnamed_addr #0 !dbg !11 { +entry: + call void @llvm.dbg.value(metadata %struct.s1* %arg1, metadata !29, metadata !DIExpression()), !dbg !35 + call void @llvm.dbg.value(metadata %union.u1* %arg2, metadata !30, metadata !DIExpression()), !dbg !35 + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %arg1, i32 0, i32 0), !dbg !36, !llvm.preserve.access.index !16 + %1 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %0, i64 2), !dbg !37 + call void @llvm.dbg.value(metadata i32 %1, metadata !31, metadata !DIExpression()), !dbg !35 + %2 = tail call i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %arg1, i32 1, i32 2), !dbg !38, !llvm.preserve.access.index !16 + %3 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %2, i64 2), !dbg !39 + call void @llvm.dbg.value(metadata i32 %3, metadata !32, metadata !DIExpression()), !dbg !35 + %4 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg2, i32 0), !dbg !40, !llvm.preserve.access.index !23 + %b1 = getelementptr inbounds %union.u1, %union.u1* %4, i64 0, i32 0, !dbg !40 + %5 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %b1, i64 2), !dbg !41 + call void @llvm.dbg.value(metadata i32 %5, metadata !33, metadata !DIExpression()), !dbg !35 + %6 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_union.u1s(%union.u1* elementtype(%union.u1) %arg2, i32 0, i32 2), !dbg !42, !llvm.preserve.access.index !23 + %7 = bitcast i32* %6 to i8*, !dbg !42 + %8 = tail call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %7, i64 2), !dbg !43 + call void @llvm.dbg.value(metadata i32 %8, metadata !34, metadata !DIExpression()), !dbg !35 + %add = add i32 %3, %1, !dbg !44 + %add1 = add i32 %add, %5, !dbg !45 + %add2 = add i32 %add1, %8, !dbg !46 + ret i32 %add2, !dbg !47 +} + +; CHECK: mov64 r1, 1 +; CHECK: mov64 r0, 1 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: mov64 r1, 1 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: mov64 r1, 1 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 2) +; CHECK: .long 37 # BTF_KIND_UNION(id = 7) +; CHECK: .ascii "s1" # string offset=1 +; CHECK: .ascii "u1" # string offset=37 +; CHECK: .ascii ".text" # string offset=64 +; CHECK: .ascii "0:0" # string offset=70 +; CHECK: .ascii "0:2" # string offset=111 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 64 # Field reloc section string offset=64 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 70 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 111 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 70 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 111 +; CHECK-NEXT: .long 2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone +declare i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i16(i16*, i64) #1 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_union.u1s(%union.u1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i8(i8*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 4, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_EXISTENCE", value: 2, isUnsigned: true) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)"} +!11 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 5, type: !12, scopeLine: 5, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !28) +!12 = !DISubroutineType(types: !13) +!13 = !{!14, !15, !22} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 2, size: 64, elements: !17) +!17 = !{!18, !19, !21} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !16, file: !1, line: 2, baseType: !14, size: 32) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !16, file: !1, line: 2, baseType: !20, size: 9, offset: 32, flags: DIFlagBitField, extraData: i64 32) +!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "__uint", file: !1, line: 1, baseType: !4) +!21 = !DIDerivedType(tag: DW_TAG_member, name: "a3", scope: !16, file: !1, line: 2, baseType: !20, size: 4, offset: 41, flags: DIFlagBitField, extraData: i64 32) +!22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !23, size: 64) +!23 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 3, size: 32, elements: !24) +!24 = !{!25, !26, !27} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !23, file: !1, line: 3, baseType: !14, size: 32) +!26 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !23, file: !1, line: 3, baseType: !20, size: 9, flags: DIFlagBitField, extraData: i64 0) +!27 = !DIDerivedType(tag: DW_TAG_member, name: "b3", scope: !23, file: !1, line: 3, baseType: !20, size: 4, flags: DIFlagBitField, extraData: i64 0) +!28 = !{!29, !30, !31, !32, !33, !34} +!29 = !DILocalVariable(name: "arg1", arg: 1, scope: !11, file: !1, line: 5, type: !15) +!30 = !DILocalVariable(name: "arg2", arg: 2, scope: !11, file: !1, line: 5, type: !22) +!31 = !DILocalVariable(name: "r1", scope: !11, file: !1, line: 6, type: !4) +!32 = !DILocalVariable(name: "r2", scope: !11, file: !1, line: 7, type: !4) +!33 = !DILocalVariable(name: "r3", scope: !11, file: !1, line: 8, type: !4) +!34 = !DILocalVariable(name: "r4", scope: !11, file: !1, line: 9, type: !4) +!35 = !DILocation(line: 0, scope: !11) +!36 = !DILocation(line: 6, column: 53, scope: !11) +!37 = !DILocation(line: 6, column: 17, scope: !11) +!38 = !DILocation(line: 7, column: 53, scope: !11) +!39 = !DILocation(line: 7, column: 17, scope: !11) +!40 = !DILocation(line: 8, column: 53, scope: !11) +!41 = !DILocation(line: 8, column: 17, scope: !11) +!42 = !DILocation(line: 9, column: 53, scope: !11) +!43 = !DILocation(line: 9, column: 17, scope: !11) +!44 = !DILocation(line: 10, column: 13, scope: !11) +!45 = !DILocation(line: 10, column: 18, scope: !11) +!46 = !DILocation(line: 10, column: 23, scope: !11) +!47 = !DILocation(line: 10, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-2.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-2.ll new file mode 100644 index 00000000000000..f79d02795da831 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-2.ll @@ -0,0 +1,125 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; typedef unsigned __uint; +; struct s1 { int a1; __uint a2:9; __uint a3:4; }; +; union u1 { int b1; struct s1 b2; }; +; enum { FIELD_EXISTENCE = 2, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2.a1, FIELD_EXISTENCE); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a3, FIELD_EXISTENCE); +; return r1 + r2; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { %struct.s1 } +%struct.s1 = type { i32, i16 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !11 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !27, metadata !DIExpression()), !dbg !30 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !31, !llvm.preserve.access.index !16 + %b2 = getelementptr inbounds %union.u1, %union.u1* %0, i64 0, i32 0, !dbg !31 + %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !32, !llvm.preserve.access.index !20 + %2 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %1, i64 2), !dbg !33 + call void @llvm.dbg.value(metadata i32 %2, metadata !28, metadata !DIExpression()), !dbg !30 + %3 = tail call i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 1, i32 2), !dbg !34, !llvm.preserve.access.index !20 + %4 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %3, i64 2), !dbg !35 + call void @llvm.dbg.value(metadata i32 %4, metadata !29, metadata !DIExpression()), !dbg !30 + %add = add i32 %4, %2, !dbg !36 + ret i32 %add, !dbg !37 +} + +; CHECK: mov64 r1, 1 +; CHECK: mov64 r0, 1 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=55 +; CHECK: .ascii "0:1:0" # string offset=61 +; CHECK: .ascii "0:1:2" # string offset=104 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 55 # Field reloc section string offset=55 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 61 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 104 +; CHECK-NEXT: .long 2 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone +declare i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i16(i16*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 4, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_EXISTENCE", value: 2, isUnsigned: true) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)"} +!11 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 5, type: !12, scopeLine: 5, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !26) +!12 = !DISubroutineType(types: !13) +!13 = !{!14, !15} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 3, size: 64, elements: !17) +!17 = !{!18, !19} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !16, file: !1, line: 3, baseType: !14, size: 32) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !16, file: !1, line: 3, baseType: !20, size: 64) +!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 2, size: 64, elements: !21) +!21 = !{!22, !23, !25} +!22 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !20, file: !1, line: 2, baseType: !14, size: 32) +!23 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !20, file: !1, line: 2, baseType: !24, size: 9, offset: 32, flags: DIFlagBitField, extraData: i64 32) +!24 = !DIDerivedType(tag: DW_TAG_typedef, name: "__uint", file: !1, line: 1, baseType: !4) +!25 = !DIDerivedType(tag: DW_TAG_member, name: "a3", scope: !20, file: !1, line: 2, baseType: !24, size: 4, offset: 41, flags: DIFlagBitField, extraData: i64 32) +!26 = !{!27, !28, !29} +!27 = !DILocalVariable(name: "arg", arg: 1, scope: !11, file: !1, line: 5, type: !15) +!28 = !DILocalVariable(name: "r1", scope: !11, file: !1, line: 6, type: !4) +!29 = !DILocalVariable(name: "r2", scope: !11, file: !1, line: 7, type: !4) +!30 = !DILocation(line: 0, scope: !11) +!31 = !DILocation(line: 6, column: 52, scope: !11) +!32 = !DILocation(line: 6, column: 55, scope: !11) +!33 = !DILocation(line: 6, column: 17, scope: !11) +!34 = !DILocation(line: 7, column: 55, scope: !11) +!35 = !DILocation(line: 7, column: 17, scope: !11) +!36 = !DILocation(line: 8, column: 13, scope: !11) +!37 = !DILocation(line: 8, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-3.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-3.ll new file mode 100644 index 00000000000000..c50d135479b47a --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-3.ll @@ -0,0 +1,133 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; typedef struct s1 { int a1[10][10]; } __s1; +; union u1 { int b1; __s1 b2; }; +; enum { FIELD_EXISTENCE = 2, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2.a1[5], FIELD_EXISTENCE); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a1[5][5], FIELD_EXISTENCE); +; return r1 + r2; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { %struct.s1 } +%struct.s1 = type { [10 x [10 x i32]] } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !18 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !31, metadata !DIExpression()), !dbg !34 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !35, !llvm.preserve.access.index !22 + %b2 = getelementptr inbounds %union.u1, %union.u1* %0, i64 0, i32 0, !dbg !35 + %1 = tail call [10 x [10 x i32]]* @llvm.preserve.struct.access.index.p0a10a10i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !36, !llvm.preserve.access.index !27 + %2 = tail call [10 x i32]* @llvm.preserve.array.access.index.p0a10i32.p0a10a10i32([10 x [10 x i32]]* elementtype([10 x [10 x i32]]) %1, i32 1, i32 5), !dbg !37, !llvm.preserve.access.index !8 + %3 = tail call i32 @llvm.bpf.preserve.field.info.p0a10i32([10 x i32]* %2, i64 2), !dbg !38 + call void @llvm.dbg.value(metadata i32 %3, metadata !32, metadata !DIExpression()), !dbg !34 + %4 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a10i32([10 x i32]* elementtype([10 x i32]) %2, i32 1, i32 5), !dbg !39, !llvm.preserve.access.index !12 + %5 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %4, i64 2), !dbg !40 + call void @llvm.dbg.value(metadata i32 %5, metadata !33, metadata !DIExpression()), !dbg !34 + %add = add i32 %5, %3, !dbg !41 + ret i32 %add, !dbg !42 +} + +; CHECK: mov64 r1, 1 +; CHECK: mov64 r0, 1 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=54 +; CHECK: .ascii "0:1:0:5" # string offset=60 +; CHECK: .ascii "0:1:0:5:5" # string offset=105 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 54 # Field reloc section string offset=54 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 60 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 105 +; CHECK-NEXT: .long 2 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare [10 x [10 x i32]]* @llvm.preserve.struct.access.index.p0a10a10i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare [10 x i32]* @llvm.preserve.array.access.index.p0a10i32.p0a10a10i32([10 x [10 x i32]]*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0a10i32([10 x i32]*, i64) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.array.access.index.p0i32.p0a10i32([10 x i32]*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!14, !15, !16} +!llvm.ident = !{!17} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git c1e02f16f1105ffaf1c35ee8bc38b7d6db5c6ea9)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !7, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 3, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_EXISTENCE", value: 2, isUnsigned: true) +!7 = !{!8, !12} +!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 3200, elements: !10) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !{!11, !11} +!11 = !DISubrange(count: 10) +!12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 320, elements: !13) +!13 = !{!11} +!14 = !{i32 2, !"Dwarf Version", i32 4} +!15 = !{i32 2, !"Debug Info Version", i32 3} +!16 = !{i32 1, !"wchar_size", i32 4} +!17 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git c1e02f16f1105ffaf1c35ee8bc38b7d6db5c6ea9)"} +!18 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !19, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !30) +!19 = !DISubroutineType(types: !20) +!20 = !{!9, !21} +!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !22, size: 64) +!22 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 2, size: 3200, elements: !23) +!23 = !{!24, !25} +!24 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !22, file: !1, line: 2, baseType: !9, size: 32) +!25 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !22, file: !1, line: 2, baseType: !26, size: 3200) +!26 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s1", file: !1, line: 1, baseType: !27) +!27 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 3200, elements: !28) +!28 = !{!29} +!29 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !27, file: !1, line: 1, baseType: !8, size: 3200) +!30 = !{!31, !32, !33} +!31 = !DILocalVariable(name: "arg", arg: 1, scope: !18, file: !1, line: 4, type: !21) +!32 = !DILocalVariable(name: "r1", scope: !18, file: !1, line: 5, type: !4) +!33 = !DILocalVariable(name: "r2", scope: !18, file: !1, line: 6, type: !4) +!34 = !DILocation(line: 0, scope: !18) +!35 = !DILocation(line: 5, column: 52, scope: !18) +!36 = !DILocation(line: 5, column: 55, scope: !18) +!37 = !DILocation(line: 5, column: 47, scope: !18) +!38 = !DILocation(line: 5, column: 17, scope: !18) +!39 = !DILocation(line: 6, column: 47, scope: !18) +!40 = !DILocation(line: 6, column: 17, scope: !18) +!41 = !DILocation(line: 7, column: 13, scope: !18) +!42 = !DILocation(line: 7, column: 3, scope: !18) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-4.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-4.ll new file mode 100644 index 00000000000000..4e9a0183026767 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-existence-4.ll @@ -0,0 +1,109 @@ +; RUN: opt -O2 -mtriple=sbf %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; Source code: +; #define BPF_FIELD_EXISTS 2 +; unsigned test1() { +; struct t { +; int val; +; } bar; +; return __builtin_preserve_field_info((&bar)[1], BPF_FIELD_EXISTS); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +%struct.t = type { i32 } + +; Function Attrs: nounwind +define dso_local i32 @test1() #0 !dbg !6 { +entry: + %bar = alloca %struct.t, align 4 + %0 = bitcast %struct.t* %bar to i8*, !dbg !20 + call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #5, !dbg !20 + call void @llvm.dbg.declare(metadata %struct.t* %bar, metadata !11, metadata !DIExpression()), !dbg !21 + %1 = call %struct.t* @llvm.preserve.array.access.index.p0s_struct.ts.p0s_struct.ts(%struct.t* elementtype(%struct.t) %bar, i32 0, i32 1), !dbg !22, !llvm.preserve.access.index !4 + %2 = call i32 @llvm.bpf.preserve.field.info.p0s_struct.ts(%struct.t* %1, i64 2), !dbg !23 + %3 = bitcast %struct.t* %bar to i8*, !dbg !24 + call void @llvm.lifetime.end.p0i8(i64 4, i8* %3) #5, !dbg !24 + ret i32 %2, !dbg !25 +} + +; CHECK: mov64 r0, 1 +; CHECK-NEXT: exit + +; CHECK: .long 26 # BTF_KIND_STRUCT(id = 4) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 32 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 + +; CHECK: .byte 116 # string offset=26 +; CHECK: .ascii "val" # string offset=28 +; CHECK: .ascii "int" # string offset=32 +; CHECK: .byte 49 # string offset=36 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long {{[0-9]+}} # Field reloc section string +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 2 + +; Function Attrs: argmemonly nofree nosync nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +; Function Attrs: nofree nosync nounwind readnone willreturn +declare %struct.t* @llvm.preserve.array.access.index.p0s_struct.ts.p0s_struct.ts(%struct.t*, i32 immarg, i32 immarg) #3 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0s_struct.ts(%struct.t*, i64 immarg) #4 + +; Function Attrs: argmemonly nofree nosync nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { argmemonly nofree nosync nounwind willreturn } +attributes #2 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #3 = { nofree nosync nounwind readnone willreturn } +attributes #4 = { nounwind readnone } +attributes #5 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!15, !16, !17, !18} +!llvm.ident = !{!19} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 2e0ee68dc85c0a2b7e65e489a60ab363393b06a8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", scope: !6, file: !1, line: 3, size: 32, elements: !12) +!6 = distinct !DISubprogram(name: "test1", scope: !1, file: !1, line: 2, type: !7, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) +!7 = !DISubroutineType(types: !8) +!8 = !{!9} +!9 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!10 = !{!11} +!11 = !DILocalVariable(name: "bar", scope: !6, file: !1, line: 5, type: !5) +!12 = !{!13} +!13 = !DIDerivedType(tag: DW_TAG_member, name: "val", scope: !5, file: !1, line: 4, baseType: !14, size: 32) +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !{i32 7, !"Dwarf Version", i32 4} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{i32 1, !"wchar_size", i32 4} +!18 = !{i32 7, !"frame-pointer", i32 2} +!19 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 2e0ee68dc85c0a2b7e65e489a60ab363393b06a8)"} +!20 = !DILocation(line: 3, column: 3, scope: !6) +!21 = !DILocation(line: 5, column: 5, scope: !6) +!22 = !DILocation(line: 6, column: 40, scope: !6) +!23 = !DILocation(line: 6, column: 10, scope: !6) +!24 = !DILocation(line: 7, column: 1, scope: !6) +!25 = !DILocation(line: 6, column: 3, scope: !6) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-lshift-1.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-lshift-1.ll new file mode 100644 index 00000000000000..9396868d18f944 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-lshift-1.ll @@ -0,0 +1,155 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU32 %s +; Source code: +; typedef struct s1 { int a1:7; int a2:4; int a3:5; int a4:16;} __s1; +; union u1 { int b1; __s1 b2; }; +; enum { FIELD_LSHIFT_U64 = 4, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2.a1, FIELD_LSHIFT_U64); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a2, FIELD_LSHIFT_U64); +; unsigned r3 = __builtin_preserve_field_info(arg->b2.a3, FIELD_LSHIFT_U64); +; unsigned r4 = __builtin_preserve_field_info(arg->b2.a4, FIELD_LSHIFT_U64); +; /* big endian: r1: 32, r2: 39, r3: 43, r4: 48 */ +; /* little endian: r1: 57, r2: 53, r3: 48, r4: 32 */ +; return r1 + r2 + r3 + r4; +; } +; Compilation flag: +; clang -target bpfel -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { i32 } +%struct.s1 = type { i32 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !11 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !28, metadata !DIExpression()), !dbg !33 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !34, !llvm.preserve.access.index !16 + %b2 = bitcast %union.u1* %0 to %struct.s1*, !dbg !34 + %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !35, !llvm.preserve.access.index !21 + %2 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %1, i64 4), !dbg !36 + call void @llvm.dbg.value(metadata i32 %2, metadata !29, metadata !DIExpression()), !dbg !33 + %3 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 1), !dbg !37, !llvm.preserve.access.index !21 + %4 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %3, i64 4), !dbg !38 + call void @llvm.dbg.value(metadata i32 %4, metadata !30, metadata !DIExpression()), !dbg !33 + %5 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 2), !dbg !39, !llvm.preserve.access.index !21 + %6 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %5, i64 4), !dbg !40 + call void @llvm.dbg.value(metadata i32 %6, metadata !31, metadata !DIExpression()), !dbg !33 + %7 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 3), !dbg !41, !llvm.preserve.access.index !21 + %8 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %7, i64 4), !dbg !42 + call void @llvm.dbg.value(metadata i32 %8, metadata !32, metadata !DIExpression()), !dbg !33 + %add = add i32 %4, %2, !dbg !43 + %add4 = add i32 %add, %6, !dbg !44 + %add5 = add i32 %add4, %8, !dbg !45 + ret i32 %add5, !dbg !46 +} + +; CHECK-EL: mov64 r1, 57 +; CHECK-EL: mov64 r0, 53 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK-EL: mov64 r1, 48 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK-EL: mov64 r1, 32 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=43 +; CHECK: .ascii "0:1:0" # string offset=49 +; CHECK: .ascii "0:1:1" # string offset=92 +; CHECK: .ascii "0:1:2" # string offset=98 +; CHECK: .ascii "0:1:3" # string offset=104 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 43 # Field reloc section string offset=43 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 49 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 92 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 98 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 104 +; CHECK-NEXT: .long 4 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 5635073377f153f7f2ff9b34c77af3c79885ff4a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 3, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_LSHIFT_U64", value: 4, isUnsigned: true) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 5635073377f153f7f2ff9b34c77af3c79885ff4a)"} +!11 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !27) +!12 = !DISubroutineType(types: !13) +!13 = !{!14, !15} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 2, size: 32, elements: !17) +!17 = !{!18, !19} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !16, file: !1, line: 2, baseType: !14, size: 32) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !16, file: !1, line: 2, baseType: !20, size: 32) +!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s1", file: !1, line: 1, baseType: !21) +!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 32, elements: !22) +!22 = !{!23, !24, !25, !26} +!23 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !21, file: !1, line: 1, baseType: !14, size: 7, flags: DIFlagBitField, extraData: i64 0) +!24 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !21, file: !1, line: 1, baseType: !14, size: 4, offset: 7, flags: DIFlagBitField, extraData: i64 0) +!25 = !DIDerivedType(tag: DW_TAG_member, name: "a3", scope: !21, file: !1, line: 1, baseType: !14, size: 5, offset: 11, flags: DIFlagBitField, extraData: i64 0) +!26 = !DIDerivedType(tag: DW_TAG_member, name: "a4", scope: !21, file: !1, line: 1, baseType: !14, size: 16, offset: 16, flags: DIFlagBitField, extraData: i64 0) +!27 = !{!28, !29, !30, !31, !32} +!28 = !DILocalVariable(name: "arg", arg: 1, scope: !11, file: !1, line: 4, type: !15) +!29 = !DILocalVariable(name: "r1", scope: !11, file: !1, line: 5, type: !4) +!30 = !DILocalVariable(name: "r2", scope: !11, file: !1, line: 6, type: !4) +!31 = !DILocalVariable(name: "r3", scope: !11, file: !1, line: 7, type: !4) +!32 = !DILocalVariable(name: "r4", scope: !11, file: !1, line: 8, type: !4) +!33 = !DILocation(line: 0, scope: !11) +!34 = !DILocation(line: 5, column: 52, scope: !11) +!35 = !DILocation(line: 5, column: 55, scope: !11) +!36 = !DILocation(line: 5, column: 17, scope: !11) +!37 = !DILocation(line: 6, column: 55, scope: !11) +!38 = !DILocation(line: 6, column: 17, scope: !11) +!39 = !DILocation(line: 7, column: 55, scope: !11) +!40 = !DILocation(line: 7, column: 17, scope: !11) +!41 = !DILocation(line: 8, column: 55, scope: !11) +!42 = !DILocation(line: 8, column: 17, scope: !11) +!43 = !DILocation(line: 11, column: 13, scope: !11) +!44 = !DILocation(line: 11, column: 18, scope: !11) +!45 = !DILocation(line: 11, column: 23, scope: !11) +!46 = !DILocation(line: 11, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-lshift-2.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-lshift-2.ll new file mode 100644 index 00000000000000..a6395bbcac14ef --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-lshift-2.ll @@ -0,0 +1,126 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; typedef struct s1 { int a1; short a2; } __s1; +; union u1 { int b1; __s1 b2; }; +; enum { FIELD_LSHIFT_U64 = 4, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2.a1, FIELD_LSHIFT_U64); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a2, FIELD_LSHIFT_U64); +; /* big endian: r1: 32, r2: 48 */ +; /* little endian: r1: 32, r2: 48 */ +; return r1 + r2; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { %struct.s1 } +%struct.s1 = type { i32, i16 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !11 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !27, metadata !DIExpression()), !dbg !30 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !31, !llvm.preserve.access.index !16 + %b2 = getelementptr %union.u1, %union.u1* %0, i64 0, i32 0, !dbg !31 + %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !32, !llvm.preserve.access.index !21 + %2 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %1, i64 4), !dbg !33 + call void @llvm.dbg.value(metadata i32 %2, metadata !28, metadata !DIExpression()), !dbg !30 + %3 = tail call i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 1, i32 1), !dbg !34, !llvm.preserve.access.index !21 + %4 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %3, i64 4), !dbg !35 + call void @llvm.dbg.value(metadata i32 %4, metadata !29, metadata !DIExpression()), !dbg !30 + %add = add i32 %4, %2, !dbg !36 + ret i32 %add, !dbg !37 +} + +; CHECK: mov64 r1, 32 +; CHECK: mov64 r0, 48 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=43 +; CHECK: .ascii "0:1:0" # string offset=49 +; CHECK: .ascii "0:1:1" # string offset=92 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 43 # Field reloc section string offset=43 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 49 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 92 +; CHECK-NEXT: .long 4 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone +declare i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i16(i16*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 5635073377f153f7f2ff9b34c77af3c79885ff4a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 3, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_LSHIFT_U64", value: 4, isUnsigned: true) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 5635073377f153f7f2ff9b34c77af3c79885ff4a)"} +!11 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !26) +!12 = !DISubroutineType(types: !13) +!13 = !{!14, !15} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 2, size: 64, elements: !17) +!17 = !{!18, !19} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !16, file: !1, line: 2, baseType: !14, size: 32) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !16, file: !1, line: 2, baseType: !20, size: 64) +!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s1", file: !1, line: 1, baseType: !21) +!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 64, elements: !22) +!22 = !{!23, !24} +!23 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !21, file: !1, line: 1, baseType: !14, size: 32) +!24 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !21, file: !1, line: 1, baseType: !25, size: 16, offset: 32) +!25 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) +!26 = !{!27, !28, !29} +!27 = !DILocalVariable(name: "arg", arg: 1, scope: !11, file: !1, line: 4, type: !15) +!28 = !DILocalVariable(name: "r1", scope: !11, file: !1, line: 5, type: !4) +!29 = !DILocalVariable(name: "r2", scope: !11, file: !1, line: 6, type: !4) +!30 = !DILocation(line: 0, scope: !11) +!31 = !DILocation(line: 5, column: 52, scope: !11) +!32 = !DILocation(line: 5, column: 55, scope: !11) +!33 = !DILocation(line: 5, column: 17, scope: !11) +!34 = !DILocation(line: 6, column: 55, scope: !11) +!35 = !DILocation(line: 6, column: 17, scope: !11) +!36 = !DILocation(line: 9, column: 13, scope: !11) +!37 = !DILocation(line: 9, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-rshift-1.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-rshift-1.ll new file mode 100644 index 00000000000000..18dcfced25e66b --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-rshift-1.ll @@ -0,0 +1,154 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; typedef struct s1 { int a1:7; int a2:4; int a3:5; int a4:16;} __s1; +; union u1 { int b1; __s1 b2; }; +; enum { FIELD_RSHIFT_U64 = 5, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2.a1, FIELD_RSHIFT_U64); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a2, FIELD_RSHIFT_U64); +; unsigned r3 = __builtin_preserve_field_info(arg->b2.a3, FIELD_RSHIFT_U64); +; unsigned r4 = __builtin_preserve_field_info(arg->b2.a4, FIELD_RSHIFT_U64); +; /* r1: 57, r2: 60, r3: 59, r4: 48 */ +; return r1 + r2 + r3 + r4; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { i32 } +%struct.s1 = type { i32 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !11 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !28, metadata !DIExpression()), !dbg !33 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !34, !llvm.preserve.access.index !16 + %b2 = bitcast %union.u1* %0 to %struct.s1*, !dbg !34 + %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !35, !llvm.preserve.access.index !21 + %2 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %1, i64 5), !dbg !36 + call void @llvm.dbg.value(metadata i32 %2, metadata !29, metadata !DIExpression()), !dbg !33 + %3 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 1), !dbg !37, !llvm.preserve.access.index !21 + %4 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %3, i64 5), !dbg !38 + call void @llvm.dbg.value(metadata i32 %4, metadata !30, metadata !DIExpression()), !dbg !33 + %5 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 2), !dbg !39, !llvm.preserve.access.index !21 + %6 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %5, i64 5), !dbg !40 + call void @llvm.dbg.value(metadata i32 %6, metadata !31, metadata !DIExpression()), !dbg !33 + %7 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 3), !dbg !41, !llvm.preserve.access.index !21 + %8 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %7, i64 5), !dbg !42 + call void @llvm.dbg.value(metadata i32 %8, metadata !32, metadata !DIExpression()), !dbg !33 + %add = add i32 %4, %2, !dbg !43 + %add4 = add i32 %add, %6, !dbg !44 + %add5 = add i32 %add4, %8, !dbg !45 + ret i32 %add5, !dbg !46 +} + +; CHECK: mov64 r1, 57 +; CHECK: mov64 r0, 60 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: mov64 r1, 59 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: mov64 r1, 48 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=43 +; CHECK: .ascii "0:1:0" # string offset=49 +; CHECK: .ascii "0:1:1" # string offset=92 +; CHECK: .ascii "0:1:2" # string offset=98 +; CHECK: .ascii "0:1:3" # string offset=104 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 43 # Field reloc section string offset=43 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 49 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 92 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 98 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 104 +; CHECK-NEXT: .long 5 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 3, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_RSHIFT_U64", value: 5, isUnsigned: true) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)"} +!11 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !27) +!12 = !DISubroutineType(types: !13) +!13 = !{!14, !15} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 2, size: 32, elements: !17) +!17 = !{!18, !19} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !16, file: !1, line: 2, baseType: !14, size: 32) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !16, file: !1, line: 2, baseType: !20, size: 32) +!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s1", file: !1, line: 1, baseType: !21) +!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 32, elements: !22) +!22 = !{!23, !24, !25, !26} +!23 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !21, file: !1, line: 1, baseType: !14, size: 7, flags: DIFlagBitField, extraData: i64 0) +!24 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !21, file: !1, line: 1, baseType: !14, size: 4, offset: 7, flags: DIFlagBitField, extraData: i64 0) +!25 = !DIDerivedType(tag: DW_TAG_member, name: "a3", scope: !21, file: !1, line: 1, baseType: !14, size: 5, offset: 11, flags: DIFlagBitField, extraData: i64 0) +!26 = !DIDerivedType(tag: DW_TAG_member, name: "a4", scope: !21, file: !1, line: 1, baseType: !14, size: 16, offset: 16, flags: DIFlagBitField, extraData: i64 0) +!27 = !{!28, !29, !30, !31, !32} +!28 = !DILocalVariable(name: "arg", arg: 1, scope: !11, file: !1, line: 4, type: !15) +!29 = !DILocalVariable(name: "r1", scope: !11, file: !1, line: 5, type: !4) +!30 = !DILocalVariable(name: "r2", scope: !11, file: !1, line: 6, type: !4) +!31 = !DILocalVariable(name: "r3", scope: !11, file: !1, line: 7, type: !4) +!32 = !DILocalVariable(name: "r4", scope: !11, file: !1, line: 8, type: !4) +!33 = !DILocation(line: 0, scope: !11) +!34 = !DILocation(line: 5, column: 52, scope: !11) +!35 = !DILocation(line: 5, column: 55, scope: !11) +!36 = !DILocation(line: 5, column: 17, scope: !11) +!37 = !DILocation(line: 6, column: 55, scope: !11) +!38 = !DILocation(line: 6, column: 17, scope: !11) +!39 = !DILocation(line: 7, column: 55, scope: !11) +!40 = !DILocation(line: 7, column: 17, scope: !11) +!41 = !DILocation(line: 8, column: 55, scope: !11) +!42 = !DILocation(line: 8, column: 17, scope: !11) +!43 = !DILocation(line: 10, column: 13, scope: !11) +!44 = !DILocation(line: 10, column: 18, scope: !11) +!45 = !DILocation(line: 10, column: 23, scope: !11) +!46 = !DILocation(line: 10, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-rshift-2.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-rshift-2.ll new file mode 100644 index 00000000000000..f09d71daef90da --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-rshift-2.ll @@ -0,0 +1,125 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; typedef struct s1 { int a1; char a2; } __s1; +; union u1 { int b1; __s1 b2; }; +; enum { FIELD_RSHIFT_U64 = 5, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2.a1, FIELD_RSHIFT_U64); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a2, FIELD_RSHIFT_U64); +; /* r1: 32, r2: 56 */ +; return r1 + r2; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { %struct.s1 } +%struct.s1 = type { i32, i8 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !11 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !27, metadata !DIExpression()), !dbg !30 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !31, !llvm.preserve.access.index !16 + %b2 = getelementptr inbounds %union.u1, %union.u1* %0, i64 0, i32 0, !dbg !31 + %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !32, !llvm.preserve.access.index !21 + %2 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %1, i64 5), !dbg !33 + call void @llvm.dbg.value(metadata i32 %2, metadata !28, metadata !DIExpression()), !dbg !30 + %3 = tail call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 1, i32 1), !dbg !34, !llvm.preserve.access.index !21 + %4 = tail call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %3, i64 5), !dbg !35 + call void @llvm.dbg.value(metadata i32 %4, metadata !29, metadata !DIExpression()), !dbg !30 + %add = add i32 %4, %2, !dbg !36 + ret i32 %add, !dbg !37 +} + +; CHECK: mov64 r1, 32 +; CHECK: mov64 r0, 56 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=42 +; CHECK: .ascii "0:1:0" # string offset=48 +; CHECK: .ascii "0:1:1" # string offset=91 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 42 # Field reloc section string offset=42 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 91 +; CHECK-NEXT: .long 5 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone +declare i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i8(i8*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 3, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_RSHIFT_U64", value: 5, isUnsigned: true) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)"} +!11 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !26) +!12 = !DISubroutineType(types: !13) +!13 = !{!14, !15} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 2, size: 64, elements: !17) +!17 = !{!18, !19} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !16, file: !1, line: 2, baseType: !14, size: 32) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !16, file: !1, line: 2, baseType: !20, size: 64) +!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s1", file: !1, line: 1, baseType: !21) +!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 64, elements: !22) +!22 = !{!23, !24} +!23 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !21, file: !1, line: 1, baseType: !14, size: 32) +!24 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !21, file: !1, line: 1, baseType: !25, size: 8, offset: 32) +!25 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!26 = !{!27, !28, !29} +!27 = !DILocalVariable(name: "arg", arg: 1, scope: !11, file: !1, line: 4, type: !15) +!28 = !DILocalVariable(name: "r1", scope: !11, file: !1, line: 5, type: !4) +!29 = !DILocalVariable(name: "r2", scope: !11, file: !1, line: 6, type: !4) +!30 = !DILocation(line: 0, scope: !11) +!31 = !DILocation(line: 5, column: 52, scope: !11) +!32 = !DILocation(line: 5, column: 55, scope: !11) +!33 = !DILocation(line: 5, column: 17, scope: !11) +!34 = !DILocation(line: 6, column: 55, scope: !11) +!35 = !DILocation(line: 6, column: 17, scope: !11) +!36 = !DILocation(line: 8, column: 13, scope: !11) +!37 = !DILocation(line: 8, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-rshift-3.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-rshift-3.ll new file mode 100644 index 00000000000000..5d2cdf56043955 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-rshift-3.ll @@ -0,0 +1,135 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; typedef struct s1 { char a1 [5][5]; } __s1; +; union u1 { int b1; __s1 b2; }; +; enum { FIELD_RSHIFT_U64 = 5, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2.a1[3], FIELD_RSHIFT_U64); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a1[3][3], FIELD_RSHIFT_U64); +; /* r1 : 24, r2 : 56 */ +; return r1 + r2; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { i32, [24 x i8] } +%struct.s1 = type { [5 x [5 x i8]] } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !18 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !32, metadata !DIExpression()), !dbg !35 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !36, !llvm.preserve.access.index !23 + %b2 = bitcast %union.u1* %0 to %struct.s1*, !dbg !36 + %1 = tail call [5 x [5 x i8]]* @llvm.preserve.struct.access.index.p0a5a5i8.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !37, !llvm.preserve.access.index !28 + %2 = tail call [5 x i8]* @llvm.preserve.array.access.index.p0a5i8.p0a5a5i8([5 x [5 x i8]]* elementtype([5 x [5 x i8]]) %1, i32 1, i32 3), !dbg !38, !llvm.preserve.access.index !8 + %3 = tail call i32 @llvm.bpf.preserve.field.info.p0a5i8([5 x i8]* %2, i64 5), !dbg !39 + call void @llvm.dbg.value(metadata i32 %3, metadata !33, metadata !DIExpression()), !dbg !35 + %4 = tail call i8* @llvm.preserve.array.access.index.p0i8.p0a5i8([5 x i8]* elementtype([5 x i8]) %2, i32 1, i32 3), !dbg !40, !llvm.preserve.access.index !12 + %5 = tail call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %4, i64 5), !dbg !41 + call void @llvm.dbg.value(metadata i32 %5, metadata !34, metadata !DIExpression()), !dbg !35 + %add = add i32 %5, %3, !dbg !42 + ret i32 %add, !dbg !43 +} + +; CHECK: mov64 r1, 24 +; CHECK: mov64 r0, 56 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=59 +; CHECK: .ascii "0:1:0:3" # string offset=65 +; CHECK: .ascii "0:1:0:3:3" # string offset=110 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 59 # Field reloc section string offset=59 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 65 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 110 +; CHECK-NEXT: .long 5 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare [5 x [5 x i8]]* @llvm.preserve.struct.access.index.p0a5a5i8.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare [5 x i8]* @llvm.preserve.array.access.index.p0a5i8.p0a5a5i8([5 x [5 x i8]]*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0a5i8([5 x i8]*, i64) #1 + +; Function Attrs: nounwind readnone +declare i8* @llvm.preserve.array.access.index.p0i8.p0a5i8([5 x i8]*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i8(i8*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!14, !15, !16} +!llvm.ident = !{!17} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git c1e02f16f1105ffaf1c35ee8bc38b7d6db5c6ea9)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !7, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 3, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_RSHIFT_U64", value: 5, isUnsigned: true) +!7 = !{!8, !12} +!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 200, elements: !10) +!9 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!10 = !{!11, !11} +!11 = !DISubrange(count: 5) +!12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 40, elements: !13) +!13 = !{!11} +!14 = !{i32 2, !"Dwarf Version", i32 4} +!15 = !{i32 2, !"Debug Info Version", i32 3} +!16 = !{i32 1, !"wchar_size", i32 4} +!17 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git c1e02f16f1105ffaf1c35ee8bc38b7d6db5c6ea9)"} +!18 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !19, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !31) +!19 = !DISubroutineType(types: !20) +!20 = !{!21, !22} +!21 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !23, size: 64) +!23 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 2, size: 224, elements: !24) +!24 = !{!25, !26} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !23, file: !1, line: 2, baseType: !21, size: 32) +!26 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !23, file: !1, line: 2, baseType: !27, size: 200) +!27 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s1", file: !1, line: 1, baseType: !28) +!28 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 1, size: 200, elements: !29) +!29 = !{!30} +!30 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !28, file: !1, line: 1, baseType: !8, size: 200) +!31 = !{!32, !33, !34} +!32 = !DILocalVariable(name: "arg", arg: 1, scope: !18, file: !1, line: 4, type: !22) +!33 = !DILocalVariable(name: "r1", scope: !18, file: !1, line: 5, type: !4) +!34 = !DILocalVariable(name: "r2", scope: !18, file: !1, line: 6, type: !4) +!35 = !DILocation(line: 0, scope: !18) +!36 = !DILocation(line: 5, column: 52, scope: !18) +!37 = !DILocation(line: 5, column: 55, scope: !18) +!38 = !DILocation(line: 5, column: 47, scope: !18) +!39 = !DILocation(line: 5, column: 17, scope: !18) +!40 = !DILocation(line: 6, column: 47, scope: !18) +!41 = !DILocation(line: 6, column: 17, scope: !18) +!42 = !DILocation(line: 8, column: 13, scope: !18) +!43 = !DILocation(line: 8, column: 3, scope: !18) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-signedness-1.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-signedness-1.ll new file mode 100644 index 00000000000000..1479fdabb3b9fa --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-signedness-1.ll @@ -0,0 +1,168 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; typedef unsigned __uint; +; struct s1 { int a1; __uint a2:9; __uint a3:4; }; +; union u1 { int b1; __uint b2:9; __uint b3:4; }; +; enum { FIELD_SIGNEDNESS = 3, }; +; int test(struct s1 *arg1, union u1 *arg2) { +; unsigned r1 = __builtin_preserve_field_info(arg1->a1, FIELD_SIGNEDNESS); +; unsigned r2 = __builtin_preserve_field_info(arg1->a3, FIELD_SIGNEDNESS); +; unsigned r3 = __builtin_preserve_field_info(arg2->b1, FIELD_SIGNEDNESS); +; unsigned r4 = __builtin_preserve_field_info(arg2->b3, FIELD_SIGNEDNESS); +; return r1 + r2 + r3 + r4; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s1 = type { i32, i16 } +%union.u1 = type { i32 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%struct.s1* %arg1, %union.u1* %arg2) local_unnamed_addr #0 !dbg !11 { +entry: + call void @llvm.dbg.value(metadata %struct.s1* %arg1, metadata !29, metadata !DIExpression()), !dbg !35 + call void @llvm.dbg.value(metadata %union.u1* %arg2, metadata !30, metadata !DIExpression()), !dbg !35 + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %arg1, i32 0, i32 0), !dbg !36, !llvm.preserve.access.index !16 + %1 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %0, i64 3), !dbg !37 + call void @llvm.dbg.value(metadata i32 %1, metadata !31, metadata !DIExpression()), !dbg !35 + %2 = tail call i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %arg1, i32 1, i32 2), !dbg !38, !llvm.preserve.access.index !16 + %3 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %2, i64 3), !dbg !39 + call void @llvm.dbg.value(metadata i32 %3, metadata !32, metadata !DIExpression()), !dbg !35 + %4 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg2, i32 0), !dbg !40, !llvm.preserve.access.index !23 + %b1 = getelementptr inbounds %union.u1, %union.u1* %4, i64 0, i32 0, !dbg !40 + %5 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %b1, i64 3), !dbg !41 + call void @llvm.dbg.value(metadata i32 %5, metadata !33, metadata !DIExpression()), !dbg !35 + %6 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_union.u1s(%union.u1* elementtype(%union.u1) %arg2, i32 0, i32 2), !dbg !42, !llvm.preserve.access.index !23 + %7 = bitcast i32* %6 to i8*, !dbg !42 + %8 = tail call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %7, i64 3), !dbg !43 + call void @llvm.dbg.value(metadata i32 %8, metadata !34, metadata !DIExpression()), !dbg !35 + %add = add i32 %3, %1, !dbg !44 + %add1 = add i32 %add, %5, !dbg !45 + %add2 = add i32 %add1, %8, !dbg !46 + ret i32 %add2, !dbg !47 +} + +; CHECK: mov64 r1, 1 +; CHECK: mov64 r0, 0 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: mov64 r1, 1 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: mov64 r1, 0 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 2) +; CHECK: .long 37 # BTF_KIND_UNION(id = 7) +; CHECK: .ascii "s1" # string offset=1 +; CHECK: .ascii "u1" # string offset=37 +; CHECK: .ascii ".text" # string offset=64 +; CHECK: .ascii "0:0" # string offset=70 +; CHECK: .ascii "0:2" # string offset=111 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 64 # Field reloc section string offset=64 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 70 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 111 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 70 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 111 +; CHECK-NEXT: .long 3 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone +declare i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i16(i16*, i64) #1 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_union.u1s(%union.u1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i8(i8*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 4, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FIELD_SIGNEDNESS", value: 3, isUnsigned: true) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)"} +!11 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 5, type: !12, scopeLine: 5, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !28) +!12 = !DISubroutineType(types: !13) +!13 = !{!14, !15, !22} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 2, size: 64, elements: !17) +!17 = !{!18, !19, !21} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !16, file: !1, line: 2, baseType: !14, size: 32) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !16, file: !1, line: 2, baseType: !20, size: 9, offset: 32, flags: DIFlagBitField, extraData: i64 32) +!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "__uint", file: !1, line: 1, baseType: !4) +!21 = !DIDerivedType(tag: DW_TAG_member, name: "a3", scope: !16, file: !1, line: 2, baseType: !20, size: 4, offset: 41, flags: DIFlagBitField, extraData: i64 32) +!22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !23, size: 64) +!23 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 3, size: 32, elements: !24) +!24 = !{!25, !26, !27} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !23, file: !1, line: 3, baseType: !14, size: 32) +!26 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !23, file: !1, line: 3, baseType: !20, size: 9, flags: DIFlagBitField, extraData: i64 0) +!27 = !DIDerivedType(tag: DW_TAG_member, name: "b3", scope: !23, file: !1, line: 3, baseType: !20, size: 4, flags: DIFlagBitField, extraData: i64 0) +!28 = !{!29, !30, !31, !32, !33, !34} +!29 = !DILocalVariable(name: "arg1", arg: 1, scope: !11, file: !1, line: 5, type: !15) +!30 = !DILocalVariable(name: "arg2", arg: 2, scope: !11, file: !1, line: 5, type: !22) +!31 = !DILocalVariable(name: "r1", scope: !11, file: !1, line: 6, type: !4) +!32 = !DILocalVariable(name: "r2", scope: !11, file: !1, line: 7, type: !4) +!33 = !DILocalVariable(name: "r3", scope: !11, file: !1, line: 8, type: !4) +!34 = !DILocalVariable(name: "r4", scope: !11, file: !1, line: 9, type: !4) +!35 = !DILocation(line: 0, scope: !11) +!36 = !DILocation(line: 6, column: 53, scope: !11) +!37 = !DILocation(line: 6, column: 17, scope: !11) +!38 = !DILocation(line: 7, column: 53, scope: !11) +!39 = !DILocation(line: 7, column: 17, scope: !11) +!40 = !DILocation(line: 8, column: 53, scope: !11) +!41 = !DILocation(line: 8, column: 17, scope: !11) +!42 = !DILocation(line: 9, column: 53, scope: !11) +!43 = !DILocation(line: 9, column: 17, scope: !11) +!44 = !DILocation(line: 10, column: 13, scope: !11) +!45 = !DILocation(line: 10, column: 18, scope: !11) +!46 = !DILocation(line: 10, column: 23, scope: !11) +!47 = !DILocation(line: 10, column: 3, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-signedness-2.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-signedness-2.ll new file mode 100644 index 00000000000000..5b9373e4407af7 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-signedness-2.ll @@ -0,0 +1,156 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; enum A { AA = -1, AB = 0, }; /* signed */ +; enum B { BA = 0, BB = 1, }; /* unsigned */ +; typedef enum A __A; +; typedef enum B __B; +; typedef int __int; /* signed */ +; struct s1 { __A a1; __B a2:9; __int a3:4; }; +; union u1 { int b1; struct s1 b2; }; +; enum { FIELD_SIGNEDNESS = 3, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2.a1, FIELD_SIGNEDNESS); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a2, FIELD_SIGNEDNESS); +; unsigned r3 = __builtin_preserve_field_info(arg->b2.a3, FIELD_SIGNEDNESS); +; return r1 + r2 + r3; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { %struct.s1 } +%struct.s1 = type { i32, i16 } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !20 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !37, metadata !DIExpression()), !dbg !41 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !42, !llvm.preserve.access.index !24 + %b2 = getelementptr inbounds %union.u1, %union.u1* %0, i64 0, i32 0, !dbg !42 + %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !43, !llvm.preserve.access.index !28 + %2 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %1, i64 3), !dbg !44 + call void @llvm.dbg.value(metadata i32 %2, metadata !38, metadata !DIExpression()), !dbg !41 + %3 = tail call i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 1, i32 1), !dbg !45, !llvm.preserve.access.index !28 + %4 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %3, i64 3), !dbg !46 + call void @llvm.dbg.value(metadata i32 %4, metadata !39, metadata !DIExpression()), !dbg !41 + %5 = tail call i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 1, i32 2), !dbg !47, !llvm.preserve.access.index !28 + %6 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %5, i64 3), !dbg !48 + call void @llvm.dbg.value(metadata i32 %6, metadata !40, metadata !DIExpression()), !dbg !41 + %add = add i32 %4, %2, !dbg !49 + %add3 = add i32 %add, %6, !dbg !50 + ret i32 %add3, !dbg !51 +} + +; CHECK: mov64 r1, 1 +; CHECK: mov64 r0, 0 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: mov64 r1, 1 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=65 +; CHECK: .ascii "0:1:0" # string offset=71 +; CHECK: .ascii "0:1:1" # string offset=114 +; CHECK: .ascii "0:1:2" # string offset=120 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 65 # Field reloc section string offset=65 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 71 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 114 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 120 +; CHECK-NEXT: .long 3 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone +declare i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i16(i16*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!16, !17, !18} +!llvm.ident = !{!19} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3, !8, !13} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "A", file: !1, line: 1, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !{!6, !7} +!6 = !DIEnumerator(name: "AA", value: -1) +!7 = !DIEnumerator(name: "AB", value: 0) +!8 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "B", file: !1, line: 2, baseType: !9, size: 32, elements: !10) +!9 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!10 = !{!11, !12} +!11 = !DIEnumerator(name: "BA", value: 0, isUnsigned: true) +!12 = !DIEnumerator(name: "BB", value: 1, isUnsigned: true) +!13 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 8, baseType: !9, size: 32, elements: !14) +!14 = !{!15} +!15 = !DIEnumerator(name: "FIELD_SIGNEDNESS", value: 3, isUnsigned: true) +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{i32 1, !"wchar_size", i32 4} +!19 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4a60741b74384f14b21fdc0131ede326438840ab)"} +!20 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 9, type: !21, scopeLine: 9, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !36) +!21 = !DISubroutineType(types: !22) +!22 = !{!4, !23} +!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !24, size: 64) +!24 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 7, size: 64, elements: !25) +!25 = !{!26, !27} +!26 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !24, file: !1, line: 7, baseType: !4, size: 32) +!27 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !24, file: !1, line: 7, baseType: !28, size: 64) +!28 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 6, size: 64, elements: !29) +!29 = !{!30, !32, !34} +!30 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !28, file: !1, line: 6, baseType: !31, size: 32) +!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "__A", file: !1, line: 3, baseType: !3) +!32 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !28, file: !1, line: 6, baseType: !33, size: 9, offset: 32, flags: DIFlagBitField, extraData: i64 32) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "__B", file: !1, line: 4, baseType: !8) +!34 = !DIDerivedType(tag: DW_TAG_member, name: "a3", scope: !28, file: !1, line: 6, baseType: !35, size: 4, offset: 41, flags: DIFlagBitField, extraData: i64 32) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 5, baseType: !4) +!36 = !{!37, !38, !39, !40} +!37 = !DILocalVariable(name: "arg", arg: 1, scope: !20, file: !1, line: 9, type: !23) +!38 = !DILocalVariable(name: "r1", scope: !20, file: !1, line: 10, type: !9) +!39 = !DILocalVariable(name: "r2", scope: !20, file: !1, line: 11, type: !9) +!40 = !DILocalVariable(name: "r3", scope: !20, file: !1, line: 12, type: !9) +!41 = !DILocation(line: 0, scope: !20) +!42 = !DILocation(line: 10, column: 52, scope: !20) +!43 = !DILocation(line: 10, column: 55, scope: !20) +!44 = !DILocation(line: 10, column: 17, scope: !20) +!45 = !DILocation(line: 11, column: 55, scope: !20) +!46 = !DILocation(line: 11, column: 17, scope: !20) +!47 = !DILocation(line: 12, column: 55, scope: !20) +!48 = !DILocation(line: 12, column: 17, scope: !20) +!49 = !DILocation(line: 13, column: 13, scope: !20) +!50 = !DILocation(line: 13, column: 18, scope: !20) +!51 = !DILocation(line: 13, column: 3, scope: !20) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-signedness-3.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-signedness-3.ll new file mode 100644 index 00000000000000..9c6a8a9ba31103 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-fieldinfo-signedness-3.ll @@ -0,0 +1,153 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; Source code: +; enum A { AA = -1, AB = 0, }; +; enum B { BA = 0, BB = 1, }; +; typedef enum A __A; +; typedef enum B __B; +; typedef struct s1 { __A a1[10]; __B a2[10][10]; } __s1; +; union u1 { int b1; __s1 b2; }; +; enum { FIELD_SIGNEDNESS = 3, }; +; int test(union u1 *arg) { +; unsigned r1 = __builtin_preserve_field_info(arg->b2.a1[5], FIELD_SIGNEDNESS); +; unsigned r2 = __builtin_preserve_field_info(arg->b2.a2[5][5], FIELD_SIGNEDNESS); +; /* r1 : 1, r2 : 0 */ +; return r1 + r2; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u1 = type { %struct.s1 } +%struct.s1 = type { [10 x i32], [10 x [10 x i32]] } + +; Function Attrs: nounwind readnone +define dso_local i32 @test(%union.u1* %arg) local_unnamed_addr #0 !dbg !29 { +entry: + call void @llvm.dbg.value(metadata %union.u1* %arg, metadata !43, metadata !DIExpression()), !dbg !46 + %0 = tail call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %arg, i32 1), !dbg !47, !llvm.preserve.access.index !33 + %b2 = getelementptr inbounds %union.u1, %union.u1* %0, i64 0, i32 0, !dbg !47 + %1 = tail call [10 x i32]* @llvm.preserve.struct.access.index.p0a10i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 0, i32 0), !dbg !48, !llvm.preserve.access.index !38 + %2 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a10i32([10 x i32]* elementtype([10 x i32]) %1, i32 1, i32 5), !dbg !49, !llvm.preserve.access.index !17 + %3 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %2, i64 3), !dbg !50 + call void @llvm.dbg.value(metadata i32 %3, metadata !44, metadata !DIExpression()), !dbg !46 + %4 = tail call [10 x [10 x i32]]* @llvm.preserve.struct.access.index.p0a10a10i32.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %b2, i32 1, i32 1), !dbg !51, !llvm.preserve.access.index !38 + %5 = tail call [10 x i32]* @llvm.preserve.array.access.index.p0a10i32.p0a10a10i32([10 x [10 x i32]]* elementtype([10 x [10 x i32]]) %4, i32 1, i32 5), !dbg !52, !llvm.preserve.access.index !21 + %6 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a10i32([10 x i32]* elementtype([10 x i32]) %5, i32 1, i32 5), !dbg !52, !llvm.preserve.access.index !24 + %7 = tail call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %6, i64 3), !dbg !53 + call void @llvm.dbg.value(metadata i32 %7, metadata !45, metadata !DIExpression()), !dbg !46 + %add = add i32 %7, %3, !dbg !54 + ret i32 %add, !dbg !55 +} + +; CHECK: mov64 r1, 1 +; CHECK: mov64 r0, 0 +; CHECK-ALU64: add64 r0, r1 +; CHECK-ALU32: add32 w0, w1 +; CHECK: exit + +; CHECK: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK: .ascii "u1" # string offset=1 +; CHECK: .ascii ".text" # string offset=81 +; CHECK: .ascii "0:1:0:5" # string offset=87 +; CHECK: .ascii "0:1:1:5:5" # string offset=132 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 81 # Field reloc section string offset=81 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 87 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 132 +; CHECK-NEXT: .long 3 + +; Function Attrs: nounwind readnone +declare %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1*, i32) #1 + +; Function Attrs: nounwind readnone +declare [10 x i32]* @llvm.preserve.struct.access.index.p0a10i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.array.access.index.p0i32.p0a10i32([10 x i32]*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i32(i32*, i64) #1 + +; Function Attrs: nounwind readnone +declare [10 x [10 x i32]]* @llvm.preserve.struct.access.index.p0a10a10i32.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare [10 x i32]* @llvm.preserve.array.access.index.p0a10i32.p0a10a10i32([10 x [10 x i32]]*, i32, i32) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!25, !26, !27} +!llvm.ident = !{!28} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git c1e02f16f1105ffaf1c35ee8bc38b7d6db5c6ea9)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !16, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3, !8, !13} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "A", file: !1, line: 1, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !{!6, !7} +!6 = !DIEnumerator(name: "AA", value: -1) +!7 = !DIEnumerator(name: "AB", value: 0) +!8 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "B", file: !1, line: 2, baseType: !9, size: 32, elements: !10) +!9 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!10 = !{!11, !12} +!11 = !DIEnumerator(name: "BA", value: 0, isUnsigned: true) +!12 = !DIEnumerator(name: "BB", value: 1, isUnsigned: true) +!13 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 7, baseType: !9, size: 32, elements: !14) +!14 = !{!15} +!15 = !DIEnumerator(name: "FIELD_SIGNEDNESS", value: 3, isUnsigned: true) +!16 = !{!17, !21, !24} +!17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !18, size: 320, elements: !19) +!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "__A", file: !1, line: 3, baseType: !3) +!19 = !{!20} +!20 = !DISubrange(count: 10) +!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 3200, elements: !23) +!22 = !DIDerivedType(tag: DW_TAG_typedef, name: "__B", file: !1, line: 4, baseType: !8) +!23 = !{!20, !20} +!24 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 320, elements: !19) +!25 = !{i32 2, !"Dwarf Version", i32 4} +!26 = !{i32 2, !"Debug Info Version", i32 3} +!27 = !{i32 1, !"wchar_size", i32 4} +!28 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git c1e02f16f1105ffaf1c35ee8bc38b7d6db5c6ea9)"} +!29 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 8, type: !30, scopeLine: 8, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !42) +!30 = !DISubroutineType(types: !31) +!31 = !{!4, !32} +!32 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !33, size: 64) +!33 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1", file: !1, line: 6, size: 3520, elements: !34) +!34 = !{!35, !36} +!35 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !33, file: !1, line: 6, baseType: !4, size: 32) +!36 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !33, file: !1, line: 6, baseType: !37, size: 3520) +!37 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s1", file: !1, line: 5, baseType: !38) +!38 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 5, size: 3520, elements: !39) +!39 = !{!40, !41} +!40 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !38, file: !1, line: 5, baseType: !17, size: 320) +!41 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !38, file: !1, line: 5, baseType: !21, size: 3200, offset: 320) +!42 = !{!43, !44, !45} +!43 = !DILocalVariable(name: "arg", arg: 1, scope: !29, file: !1, line: 8, type: !32) +!44 = !DILocalVariable(name: "r1", scope: !29, file: !1, line: 9, type: !9) +!45 = !DILocalVariable(name: "r2", scope: !29, file: !1, line: 10, type: !9) +!46 = !DILocation(line: 0, scope: !29) +!47 = !DILocation(line: 9, column: 52, scope: !29) +!48 = !DILocation(line: 9, column: 55, scope: !29) +!49 = !DILocation(line: 9, column: 47, scope: !29) +!50 = !DILocation(line: 9, column: 17, scope: !29) +!51 = !DILocation(line: 10, column: 55, scope: !29) +!52 = !DILocation(line: 10, column: 47, scope: !29) +!53 = !DILocation(line: 10, column: 17, scope: !29) +!54 = !DILocation(line: 12, column: 13, scope: !29) +!55 = !DILocation(line: 12, column: 3, scope: !29) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-struct.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-struct.ll new file mode 100644 index 00000000000000..c9418a85b71d8e --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-struct.ll @@ -0,0 +1,82 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source code: +; struct s { int a; int b; }; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const void *addr); +; int test(struct s *arg) { return get_value(_(&arg->b)); } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.s* %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.s* %arg, metadata !17, metadata !DIExpression()), !dbg !18 + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s* elementtype(%struct.s) %arg, i32 1, i32 1), !dbg !19, !llvm.preserve.access.index !12 + %1 = bitcast i32* %0 to i8*, !dbg !19 + %call = tail call i32 @get_value(i8* %1) #4, !dbg !20 + ret i32 %call, !dbg !21 +} + +; CHECK-LABEL: test +; CHECK: [[RELOC:.Ltmp[0-9]+]] +; CHECK: mov64 r2, 4 +; CHECK: add64 r1, r2 +; CHECK: call get_value +; CHECK: exit +; +; CHECK: .section .BTF.ext,"",@progbits +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 20 # Field reloc section string offset=20 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long [[RELOC]] +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i8*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 (trunk 365789)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 9.0.0 (trunk 365789)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !8, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !16) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 1, size: 64, elements: !13) +!13 = !{!14, !15} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !12, file: !1, line: 1, baseType: !10, size: 32) +!15 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !12, file: !1, line: 1, baseType: !10, size: 32, offset: 32) +!16 = !{!17} +!17 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 4, type: !11) +!18 = !DILocation(line: 0, scope: !7) +!19 = !DILocation(line: 4, column: 44, scope: !7) +!20 = !DILocation(line: 4, column: 34, scope: !7) +!21 = !DILocation(line: 4, column: 27, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-enum-value-opaque-pointer.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-enum-value-opaque-pointer.ll new file mode 100644 index 00000000000000..ff5eed7fb21555 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-enum-value-opaque-pointer.ll @@ -0,0 +1,103 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source: +; enum AA { VAL1 = -100, VAL2 = 0xffff8000 }; +; typedef enum { VAL10 = 0xffffFFFF80000000 } __BB; +; int test() { +; return __builtin_preserve_enum_value(*(enum AA *)VAL1, 0) + +; __builtin_preserve_enum_value(*(enum AA *)VAL2, 1) + +; __builtin_preserve_enum_value(*(__BB *)VAL10, 1); +; } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes t1.c + +target triple = "sbf" + +@0 = private unnamed_addr constant [10 x i8] c"VAL1:-100\00", align 1 +@1 = private unnamed_addr constant [16 x i8] c"VAL2:4294934528\00", align 1 +@2 = private unnamed_addr constant [18 x i8] c"VAL10:-2147483648\00", align 1 + +; Function Attrs: nounwind +define dso_local i32 @test() #0 !dbg !19 { +entry: + %0 = call i64 @llvm.bpf.preserve.enum.value(i32 0, ptr @0, i64 0), !dbg !24, !llvm.preserve.access.index !3 + %1 = call i64 @llvm.bpf.preserve.enum.value(i32 1, ptr @1, i64 1), !dbg !25, !llvm.preserve.access.index !3 + %add = add i64 %0, %1, !dbg !26 + %2 = call i64 @llvm.bpf.preserve.enum.value(i32 2, ptr @2, i64 1), !dbg !27, !llvm.preserve.access.index !13 + %add1 = add i64 %add, %2, !dbg !28 + %conv = trunc i64 %add1 to i32, !dbg !24 + ret i32 %conv, !dbg !29 +} + +; CHECK: lddw r{{[0-9]+}}, 1 +; CHECK: lddw r{{[0-9]+}}, 4294934528 +; CHECK: lddw r{{[0-9]+}}, -2147483648 +; CHECK: exit + +; CHECK: .long 16 # BTF_KIND_ENUM64(id = 4) +; CHECK: .long 57 # BTF_KIND_TYPEDEF(id = 5) + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "AA" # string offset=16 +; CHECK: .byte 48 # string offset=29 +; CHECK: .byte 49 # string offset=55 +; CHECK: .ascii "__BB" # string offset=57 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 29 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 55 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 29 +; CHECK-NEXT: .long 11 + +; Function Attrs: nounwind readnone +declare i64 @llvm.bpf.preserve.enum.value(i32, ptr, i64) #1 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!14, !15, !16, !17} +!llvm.ident = !{!18} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 1218d7e1cf1284666cd7403ea021e40b3b40e92b)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !12, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t1.c", directory: "/tmp/home/yhs/tmp1", checksumkind: CSK_MD5, checksum: "e1a546573a450dae0abedfbf6bebcba9") +!2 = !{!3, !8} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "AA", file: !1, line: 1, baseType: !4, size: 64, elements: !5) +!4 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) +!5 = !{!6, !7} +!6 = !DIEnumerator(name: "VAL1", value: -100) +!7 = !DIEnumerator(name: "VAL2", value: 4294934528) +!8 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 2, baseType: !9, size: 64, elements: !10) +!9 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!10 = !{!11} +!11 = !DIEnumerator(name: "VAL10", value: 18446744071562067968, isUnsigned: true) +!12 = !{!13} +!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "__BB", file: !1, line: 2, baseType: !8) +!14 = !{i32 7, !"Dwarf Version", i32 5} +!15 = !{i32 2, !"Debug Info Version", i32 3} +!16 = !{i32 1, !"wchar_size", i32 4} +!17 = !{i32 7, !"frame-pointer", i32 2} +!18 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 1218d7e1cf1284666cd7403ea021e40b3b40e92b)"} +!19 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !20, scopeLine: 3, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !23) +!20 = !DISubroutineType(types: !21) +!21 = !{!22} +!22 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!23 = !{} +!24 = !DILocation(line: 4, column: 10, scope: !19) +!25 = !DILocation(line: 5, column: 10, scope: !19) +!26 = !DILocation(line: 4, column: 61, scope: !19) +!27 = !DILocation(line: 6, column: 10, scope: !19) +!28 = !DILocation(line: 5, column: 61, scope: !19) +!29 = !DILocation(line: 4, column: 3, scope: !19) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-enum-value.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-enum-value.ll new file mode 100644 index 00000000000000..6ac2c7aef33e7e --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-enum-value.ll @@ -0,0 +1,121 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source: +; enum AA { VAL1 = -100, VAL2 = 0xffff8000 }; +; typedef enum { VAL10 = 0xffffFFFF80000000 } __BB; +; int test() { +; return __builtin_preserve_enum_value(*(enum AA *)VAL1, 0) + +; __builtin_preserve_enum_value(*(enum AA *)VAL2, 1) + +; __builtin_preserve_enum_value(*(__BB *)VAL10, 1); +; } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes t1.c + +target triple = "sbf" + +@0 = private unnamed_addr constant [10 x i8] c"VAL1:-100\00", align 1 +@1 = private unnamed_addr constant [16 x i8] c"VAL2:4294934528\00", align 1 +@2 = private unnamed_addr constant [18 x i8] c"VAL10:-2147483648\00", align 1 + +; Function Attrs: nounwind readnone +define dso_local i32 @test() local_unnamed_addr #0 !dbg !18 { +entry: + %0 = tail call i64 @llvm.bpf.preserve.enum.value(i32 0, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @0, i64 0, i64 0), i64 0), !dbg !23, !llvm.preserve.access.index !3 + %1 = tail call i64 @llvm.bpf.preserve.enum.value(i32 1, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @1, i64 0, i64 0), i64 1), !dbg !24, !llvm.preserve.access.index !3 + %add = add i64 %1, %0, !dbg !25 + %2 = tail call i64 @llvm.bpf.preserve.enum.value(i32 2, i8* getelementptr inbounds ([18 x i8], [18 x i8]* @2, i64 0, i64 0), i64 1), !dbg !26, !llvm.preserve.access.index !13 + %add1 = add i64 %add, %2, !dbg !27 + %conv = trunc i64 %add1 to i32, !dbg !23 + ret i32 %conv, !dbg !28 +} + +; CHECK: lddw r{{[0-9]+}}, 1 +; CHECK: lddw r{{[0-9]+}}, 4294934528 +; CHECK: lddw r{{[0-9]+}}, -2147483648 +; CHECK: exit + +; CHECK: .long 16 # BTF_KIND_ENUM64(id = 4) +; CHECK-NEXT: .long 2466250754 # 0x93000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 19 +; CHECK-NEXT: .long 4294967196 # 0xffffff9c +; CHECK-NEXT: .long 4294967295 # 0xffffffff +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 4294934528 # 0xffff8000 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 57 # BTF_KIND_TYPEDEF(id = 5) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # BTF_KIND_ENUM64(id = 6) +; CHECK-NEXT: .long 318767105 # 0x13000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 62 +; CHECK-NEXT: .long 2147483648 # 0x80000000 +; CHECK-NEXT: .long 4294967295 # 0xffffffff + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "AA" # string offset=16 +; CHECK: .ascii "VAL1" # string offset=19 +; CHECK: .ascii "VAL2" # string offset=24 +; CHECK: .byte 48 # string offset=29 +; CHECK: .byte 49 # string offset=55 +; CHECK: .ascii "__BB" # string offset=57 +; CHECK: .ascii "VAL10" # string offset=62 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 29 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 55 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 29 +; CHECK-NEXT: .long 11 + +; Function Attrs: nounwind readnone +declare i64 @llvm.bpf.preserve.enum.value(i32, i8*, i64) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!14, !15, !16} +!llvm.ident = !{!17} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git d8b1394a0f4bbf57c254f69f8d3aa5381a89b5cd)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !12, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t1.c", directory: "/tmp/home/yhs/tmp1") +!2 = !{!3, !8} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "AA", file: !1, line: 1, baseType: !4, size: 64, elements: !5) +!4 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed) +!5 = !{!6, !7} +!6 = !DIEnumerator(name: "VAL1", value: -100) +!7 = !DIEnumerator(name: "VAL2", value: 4294934528) +!8 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 2, baseType: !9, size: 64, elements: !10) +!9 = !DIBasicType(name: "long unsigned int", size: 64, encoding: DW_ATE_unsigned) +!10 = !{!11} +!11 = !DIEnumerator(name: "VAL10", value: 18446744071562067968, isUnsigned: true) +!12 = !{!13} +!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "__BB", file: !1, line: 2, baseType: !8) +!14 = !{i32 7, !"Dwarf Version", i32 4} +!15 = !{i32 2, !"Debug Info Version", i32 3} +!16 = !{i32 1, !"wchar_size", i32 4} +!17 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git d8b1394a0f4bbf57c254f69f8d3aa5381a89b5cd)"} +!18 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !19, scopeLine: 3, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !22) +!19 = !DISubroutineType(types: !20) +!20 = !{!21} +!21 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!22 = !{} +!23 = !DILocation(line: 4, column: 10, scope: !18) +!24 = !DILocation(line: 5, column: 10, scope: !18) +!25 = !DILocation(line: 4, column: 61, scope: !18) +!26 = !DILocation(line: 6, column: 10, scope: !18) +!27 = !DILocation(line: 5, column: 61, scope: !18) +!28 = !DILocation(line: 4, column: 3, scope: !18) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-exist.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-exist.ll new file mode 100644 index 00000000000000..236118864f856c --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-exist.ll @@ -0,0 +1,101 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source: +; enum AA { VAL = 100 }; +; typedef int (*func_t)(void); +; struct s2 { int a[10]; }; +; int test() { +; return __builtin_preserve_type_info(*(func_t *)0, 0) + +; __builtin_preserve_type_info(*(struct s2 *)0, 0) + +; __builtin_preserve_type_info(*(enum AA *)0, 0); +; } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes t1.c + +target triple = "sbf" + +; Function Attrs: nounwind readnone +define dso_local i32 @test() local_unnamed_addr #0 !dbg !17 { +entry: + %0 = tail call i32 @llvm.bpf.preserve.type.info(i32 0, i64 0), !dbg !19, !llvm.preserve.access.index !8 + %1 = tail call i32 @llvm.bpf.preserve.type.info(i32 1, i64 0), !dbg !20, !llvm.preserve.access.index !21 + %add = add i32 %1, %0, !dbg !27 + %2 = tail call i32 @llvm.bpf.preserve.type.info(i32 2, i64 0), !dbg !28, !llvm.preserve.access.index !3 + %add1 = add i32 %add, %2, !dbg !29 + ret i32 %add1, !dbg !30 +} + +; CHECK: mov64 r{{[0-9]+}}, 1 +; CHECK: mov64 r{{[0-9]+}}, 1 +; CHECK: mov64 r{{[0-9]+}}, 1 +; CHECK: exit + +; CHECK: .long 16 # BTF_KIND_TYPEDEF(id = 4) +; CHECK: .long 49 # BTF_KIND_STRUCT(id = 7) +; CHECK: .long 74 # BTF_KIND_ENUM(id = 10) + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "func_t" # string offset=16 +; CHECK: .byte 48 # string offset=23 +; CHECK: .ascii "s2" # string offset=49 +; CHECK: .ascii "AA" # string offset=74 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 8 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.type.info(i32, i64) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!13, !14, !15} +!llvm.ident = !{!16} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git d8b1394a0f4bbf57c254f69f8d3aa5381a89b5cd)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !7, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t1.c", directory: "/tmp/home/yhs/tmp1") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "AA", file: !1, line: 1, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "VAL", value: 100, isUnsigned: true) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_typedef, name: "func_t", file: !1, line: 2, baseType: !9) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = !DISubroutineType(types: !11) +!11 = !{!12} +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !{i32 7, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{i32 1, !"wchar_size", i32 4} +!16 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git d8b1394a0f4bbf57c254f69f8d3aa5381a89b5cd)"} +!17 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !10, scopeLine: 4, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !18) +!18 = !{} +!19 = !DILocation(line: 5, column: 10, scope: !17) +!20 = !DILocation(line: 6, column: 10, scope: !17) +!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s2", file: !1, line: 3, size: 320, elements: !22) +!22 = !{!23} +!23 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !21, file: !1, line: 3, baseType: !24, size: 320) +!24 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 320, elements: !25) +!25 = !{!26} +!26 = !DISubrange(count: 10) +!27 = !DILocation(line: 5, column: 56, scope: !17) +!28 = !DILocation(line: 7, column: 10, scope: !17) +!29 = !DILocation(line: 6, column: 59, scope: !17) +!30 = !DILocation(line: 5, column: 3, scope: !17) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-match.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-match.ll new file mode 100644 index 00000000000000..2163cb8062c344 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-match.ll @@ -0,0 +1,103 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source: +; enum AA { VAL = 100 }; +; typedef int (*func_t)(void); +; struct s2 { int a[10]; }; +; int test() { +; return __builtin_preserve_type_info(*(func_t *)0, 2) + +; __builtin_preserve_type_info(*(struct s2 *)0, 2) + +; __builtin_preserve_type_info(*(enum AA *)0, 2); +; } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes t1.c + +source_filename = "t1.c" +target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" +target triple = "sbf" + +; Function Attrs: nounwind +define dso_local i32 @test() #0 !dbg !18 { + %1 = call i32 @llvm.bpf.preserve.type.info(i32 0, i64 2), !dbg !20, !llvm.preserve.access.index !8 + %2 = call i32 @llvm.bpf.preserve.type.info(i32 1, i64 2), !dbg !21, !llvm.preserve.access.index !22 + %3 = add i32 %1, %2, !dbg !28 + %4 = call i32 @llvm.bpf.preserve.type.info(i32 2, i64 2), !dbg !29, !llvm.preserve.access.index !3 + %5 = add i32 %3, %4, !dbg !30 + ret i32 %5, !dbg !31 +} + +; CHECK: mov64 r{{[0-9]+}}, 1 +; CHECK: mov64 r{{[0-9]+}}, 1 +; CHECK: mov64 r{{[0-9]+}}, 1 +; CHECK: exit + +; CHECK: .long 16 # BTF_KIND_TYPEDEF(id = 4) +; CHECK: .long 40 # BTF_KIND_STRUCT(id = 7) +; CHECK: .long 65 # BTF_KIND_ENUM(id = 10) + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "func_t" # string offset=16 +; CHECK: .byte 48 # string offset=23 +; CHECK: .ascii "s2" # string offset=40 +; CHECK: .ascii "AA" # string offset=65 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 12 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.type.info(i32, i64) #1 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!13, !14, !15, !16} +!llvm.ident = !{!17} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 3d974661fd15612259d37f603ddf21df7ee0e428)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !7, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t1.c", directory: "/tmp/tmp1", checksumkind: CSK_MD5, checksum: "53350e4a8003565f949c897f1fce8567") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "AA", file: !1, line: 1, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "VAL", value: 100) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_typedef, name: "func_t", file: !1, line: 2, baseType: !9) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = !DISubroutineType(types: !11) +!11 = !{!12} +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !{i32 7, !"Dwarf Version", i32 5} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{i32 1, !"wchar_size", i32 4} +!16 = !{i32 7, !"frame-pointer", i32 2} +!17 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 3d974661fd15612259d37f603ddf21df7ee0e428)"} +!18 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !10, scopeLine: 4, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !19) +!19 = !{} +!20 = !DILocation(line: 5, column: 10, scope: !18) +!21 = !DILocation(line: 6, column: 10, scope: !18) +!22 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s2", file: !1, line: 3, size: 320, elements: !23) +!23 = !{!24} +!24 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !22, file: !1, line: 3, baseType: !25, size: 320) +!25 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 320, elements: !26) +!26 = !{!27} +!27 = !DISubrange(count: 10) +!28 = !DILocation(line: 5, column: 56, scope: !18) +!29 = !DILocation(line: 7, column: 10, scope: !18) +!30 = !DILocation(line: 6, column: 59, scope: !18) +!31 = !DILocation(line: 5, column: 3, scope: !18) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-size-1.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-size-1.ll new file mode 100644 index 00000000000000..b3ed18a0158ea2 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-size-1.ll @@ -0,0 +1,101 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source: +; enum AA { VAL = 100 }; +; typedef int (*func_t)(void); +; struct s2 { int a[10]; }; +; int test() { +; return __builtin_preserve_type_info(*(func_t *)0, 1) + +; __builtin_preserve_type_info(*(struct s2 *)0, 1) + +; __builtin_preserve_type_info(*(enum AA *)0, 1); +; } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes t1.c + +target triple = "sbf" + +; Function Attrs: nounwind readnone +define dso_local i32 @test() local_unnamed_addr #0 !dbg !17 { +entry: + %0 = tail call i32 @llvm.bpf.preserve.type.info(i32 0, i64 1), !dbg !19, !llvm.preserve.access.index !8 + %1 = tail call i32 @llvm.bpf.preserve.type.info(i32 1, i64 1), !dbg !20, !llvm.preserve.access.index !21 + %add = add i32 %1, %0, !dbg !27 + %2 = tail call i32 @llvm.bpf.preserve.type.info(i32 2, i64 1), !dbg !28, !llvm.preserve.access.index !3 + %add1 = add i32 %add, %2, !dbg !29 + ret i32 %add1, !dbg !30 +} + +; CHECK: mov64 r{{[0-9]+}}, 8 +; CHECK: mov64 r{{[0-9]+}}, 40 +; CHECK: mov64 r{{[0-9]+}}, 4 +; CHECK: exit + +; CHECK: .long 16 # BTF_KIND_TYPEDEF(id = 4) +; CHECK: .long 49 # BTF_KIND_STRUCT(id = 7) +; CHECK: .long 74 # BTF_KIND_ENUM(id = 10) + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "func_t" # string offset=16 +; CHECK: .byte 48 # string offset=23 +; CHECK: .ascii "s2" # string offset=49 +; CHECK: .ascii "AA" # string offset=74 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 9 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.type.info(i32, i64) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!13, !14, !15} +!llvm.ident = !{!16} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git d8b1394a0f4bbf57c254f69f8d3aa5381a89b5cd)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !7, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t1.c", directory: "/tmp/home/yhs/tmp1") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "AA", file: !1, line: 1, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "VAL", value: 100, isUnsigned: true) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_typedef, name: "func_t", file: !1, line: 2, baseType: !9) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = !DISubroutineType(types: !11) +!11 = !{!12} +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !{i32 7, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{i32 1, !"wchar_size", i32 4} +!16 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git d8b1394a0f4bbf57c254f69f8d3aa5381a89b5cd)"} +!17 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !10, scopeLine: 4, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !18) +!18 = !{} +!19 = !DILocation(line: 5, column: 10, scope: !17) +!20 = !DILocation(line: 6, column: 10, scope: !17) +!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s2", file: !1, line: 3, size: 320, elements: !22) +!22 = !{!23} +!23 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !21, file: !1, line: 3, baseType: !24, size: 320) +!24 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 320, elements: !25) +!25 = !{!26} +!26 = !DISubrange(count: 10) +!27 = !DILocation(line: 5, column: 56, scope: !17) +!28 = !DILocation(line: 7, column: 10, scope: !17) +!29 = !DILocation(line: 6, column: 59, scope: !17) +!30 = !DILocation(line: 5, column: 3, scope: !17) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-size-2.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-size-2.ll new file mode 100644 index 00000000000000..256ca6af35b2d9 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-typeinfo-type-size-2.ll @@ -0,0 +1,117 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source: +; enum AA { VAL = 100 }; +; typedef int (*func_t)(void); +; struct s2 { int a[10]; }; +; int test() { +; func_t f; +; struct s2 s; +; enum AA a; +; return __builtin_preserve_type_info(f, 1) + +; __builtin_preserve_type_info(s, 1) + +; __builtin_preserve_type_info(a, 1); +; } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes t1.c + +target triple = "sbf" + +; Function Attrs: nounwind readnone +define dso_local i32 @test() local_unnamed_addr #0 !dbg !17 { +entry: + call void @llvm.dbg.declare(metadata [10 x i32]* undef, metadata !20, metadata !DIExpression()), !dbg !28 + call void @llvm.dbg.declare(metadata i32 ()** undef, metadata !19, metadata !DIExpression()), !dbg !29 + call void @llvm.dbg.declare(metadata i32* undef, metadata !27, metadata !DIExpression()), !dbg !30 + %0 = tail call i32 @llvm.bpf.preserve.type.info(i32 0, i64 1), !dbg !31, !llvm.preserve.access.index !8 + %1 = tail call i32 @llvm.bpf.preserve.type.info(i32 1, i64 1), !dbg !32, !llvm.preserve.access.index !21 + %add = add i32 %1, %0, !dbg !33 + %2 = tail call i32 @llvm.bpf.preserve.type.info(i32 2, i64 1), !dbg !34, !llvm.preserve.access.index !3 + %add1 = add i32 %add, %2, !dbg !35 + ret i32 %add1, !dbg !36 +} + +; CHECK: mov64 r{{[0-9]+}}, 8 +; CHECK: mov64 r{{[0-9]+}}, 40 +; CHECK: mov64 r{{[0-9]+}}, 4 +; CHECK: exit + +; CHECK: .long 16 # BTF_KIND_TYPEDEF(id = 4) +; CHECK: .long 49 # BTF_KIND_STRUCT(id = 7) +; CHECK: .long 74 # BTF_KIND_ENUM(id = 10) + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "func_t" # string offset=16 +; CHECK: .byte 48 # string offset=23 +; CHECK: .ascii "s2" # string offset=49 +; CHECK: .ascii "AA" # string offset=74 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 9 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.type.info(i32, i64) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable willreturn } +attributes #2 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!13, !14, !15} +!llvm.ident = !{!16} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git d8b1394a0f4bbf57c254f69f8d3aa5381a89b5cd)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !7, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t1.c", directory: "/tmp/home/yhs/tmp1") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "AA", file: !1, line: 1, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "VAL", value: 100, isUnsigned: true) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_typedef, name: "func_t", file: !1, line: 2, baseType: !9) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = !DISubroutineType(types: !11) +!11 = !{!12} +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !{i32 7, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{i32 1, !"wchar_size", i32 4} +!16 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git d8b1394a0f4bbf57c254f69f8d3aa5381a89b5cd)"} +!17 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !10, scopeLine: 4, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !18) +!18 = !{!19, !20, !27} +!19 = !DILocalVariable(name: "f", scope: !17, file: !1, line: 5, type: !8) +!20 = !DILocalVariable(name: "s", scope: !17, file: !1, line: 6, type: !21) +!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s2", file: !1, line: 3, size: 320, elements: !22) +!22 = !{!23} +!23 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !21, file: !1, line: 3, baseType: !24, size: 320) +!24 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 320, elements: !25) +!25 = !{!26} +!26 = !DISubrange(count: 10) +!27 = !DILocalVariable(name: "a", scope: !17, file: !1, line: 7, type: !3) +!28 = !DILocation(line: 6, column: 13, scope: !17) +!29 = !DILocation(line: 5, column: 10, scope: !17) +!30 = !DILocation(line: 7, column: 11, scope: !17) +!31 = !DILocation(line: 8, column: 10, scope: !17) +!32 = !DILocation(line: 9, column: 10, scope: !17) +!33 = !DILocation(line: 8, column: 45, scope: !17) +!34 = !DILocation(line: 10, column: 10, scope: !17) +!35 = !DILocation(line: 9, column: 45, scope: !17) +!36 = !DILocation(line: 8, column: 3, scope: !17) diff --git a/llvm/test/CodeGen/SBF/CORE/intrinsic-union.ll b/llvm/test/CodeGen/SBF/CORE/intrinsic-union.ll new file mode 100644 index 00000000000000..d926508e5c10fa --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/intrinsic-union.ll @@ -0,0 +1,81 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source code: +; union u { int a; int b; }; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const void *addr); +; int test(union u *arg) { return get_value(_(&arg->b)); } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.u = type { i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%union.u* %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %union.u* %arg, metadata !17, metadata !DIExpression()), !dbg !18 + %0 = tail call %union.u* @llvm.preserve.union.access.index.p0s_union.us.p0s_union.us(%union.u* %arg, i32 1), !dbg !19, !llvm.preserve.access.index !12 + %1 = bitcast %union.u* %0 to i8*, !dbg !19 + %call = tail call i32 @get_value(i8* %1) #4, !dbg !20 + ret i32 %call, !dbg !21 +} +; CHECK-LABEL: test +; CHECK: [[RELOC:.Ltmp[0-9]+]] +; CHECK: mov64 r2, 0 +; CHECK: add64 r1, r2 +; CHECK: call get_value +; CHECK: exit + +; CHECK: .section .BTF.ext,"",@progbits +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 20 # Field reloc section string offset=20 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long [[RELOC]] +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i8*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare %union.u* @llvm.preserve.union.access.index.p0s_union.us.p0s_union.us(%union.u*, i32 immarg) #2 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 (trunk 365789)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 9.0.0 (trunk 365789)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !8, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !16) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u", file: !1, line: 1, size: 32, elements: !13) +!13 = !{!14, !15} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !12, file: !1, line: 1, baseType: !10, size: 32) +!15 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !12, file: !1, line: 1, baseType: !10, size: 32) +!16 = !{!17} +!17 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 4, type: !11) +!18 = !DILocation(line: 0, scope: !7) +!19 = !DILocation(line: 4, column: 43, scope: !7) +!20 = !DILocation(line: 4, column: 33, scope: !7) +!21 = !DILocation(line: 4, column: 26, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/no-elf-ama-symbol.ll b/llvm/test/CodeGen/SBF/CORE/no-elf-ama-symbol.ll new file mode 100644 index 00000000000000..e74a39c0bb4d05 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/no-elf-ama-symbol.ll @@ -0,0 +1,66 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=obj -o - %t1 | llvm-readelf -s - | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -filetype=obj -addrsig -o - %t1 | llvm-readelf -s - | FileCheck -check-prefixes=CHECK %s +; +; Source Code: +; struct tt { int a; } __attribute__((preserve_access_index)); +; int test(struct tt *arg) { +; return arg->a; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes t.c + +target triple = "sbf" + +%struct.tt = type { i32 } + +; Function Attrs: nounwind readonly +define dso_local i32 @test(%struct.tt* readonly %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.tt* %arg, metadata !16, metadata !DIExpression()), !dbg !17 + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.tts(%struct.tt* elementtype(%struct.tt) %arg, i32 0, i32 0), !dbg !18, !llvm.preserve.access.index !12 + %1 = load i32, i32* %0, align 4, !dbg !18, !tbaa !19 + ret i32 %1, !dbg !24 +} + +; CHECK-NOT: llvm.tt:0:0$0:0 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.tts(%struct.tt*, i32, i32) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 947f9692440836dcb8d88b74b69dd379d85974ce)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/bug") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 947f9692440836dcb8d88b74b69dd379d85974ce)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !15) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "tt", file: !1, line: 1, size: 32, elements: !13) +!13 = !{!14} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !12, file: !1, line: 1, baseType: !10, size: 32) +!15 = !{!16} +!16 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 2, type: !11) +!17 = !DILocation(line: 0, scope: !7) +!18 = !DILocation(line: 3, column: 15, scope: !7) +!19 = !{!20, !21, i64 0} +!20 = !{!"tt", !21, i64 0} +!21 = !{!"int", !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 3, column: 3, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/no-narrow-load.ll b/llvm/test/CodeGen/SBF/CORE/no-narrow-load.ll new file mode 100644 index 00000000000000..602db2ce103dc5 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/no-narrow-load.ll @@ -0,0 +1,158 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct data_t { +; int d1; +; int d2; +; }; +; struct info_t { +; int pid; +; int flags; +; } __attribute__((preserve_access_index)); +; +; extern void output(void *); +; void test(struct info_t * args) { +; int is_mask2 = args->flags & 0x10000; +; struct data_t data = {}; +; +; data.d1 = is_mask2 ? 2 : args->pid; +; data.d2 = (is_mask2 || (args->flags & 0x8000)) ? 1 : 2; +; output(&data); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.info_t = type { i32, i32 } +%struct.data_t = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local void @test(%struct.info_t* readonly %args) local_unnamed_addr #0 !dbg !12 { +entry: + %data = alloca i64, align 8 + %tmpcast = bitcast i64* %data to %struct.data_t* + call void @llvm.dbg.value(metadata %struct.info_t* %args, metadata !22, metadata !DIExpression()), !dbg !29 + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.info_ts(%struct.info_t* elementtype(%struct.info_t) %args, i32 1, i32 1), !dbg !30, !llvm.preserve.access.index !16 + %1 = load i32, i32* %0, align 4, !dbg !30, !tbaa !31 + %and = and i32 %1, 65536, !dbg !36 + call void @llvm.dbg.value(metadata i32 %and, metadata !23, metadata !DIExpression()), !dbg !29 + %2 = bitcast i64* %data to i8*, !dbg !37 + call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %2) #5, !dbg !37 + call void @llvm.dbg.declare(metadata %struct.data_t* %tmpcast, metadata !24, metadata !DIExpression()), !dbg !38 + store i64 0, i64* %data, align 8, !dbg !38 + %tobool = icmp eq i32 %and, 0, !dbg !39 + br i1 %tobool, label %cond.false, label %lor.end.critedge, !dbg !39 + +cond.false: ; preds = %entry + %3 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.info_ts(%struct.info_t* elementtype(%struct.info_t) %args, i32 0, i32 0), !dbg !40, !llvm.preserve.access.index !16 + %4 = load i32, i32* %3, align 4, !dbg !40, !tbaa !41 + %d1 = bitcast i64* %data to i32*, !dbg !42 + store i32 %4, i32* %d1, align 8, !dbg !43, !tbaa !44 + %5 = load i32, i32* %0, align 4, !dbg !46, !tbaa !31 + %and2 = and i32 %5, 32768, !dbg !47 + %tobool3 = icmp eq i32 %and2, 0, !dbg !48 + %phitmp = select i1 %tobool3, i32 2, i32 1, !dbg !48 + br label %lor.end, !dbg !48 + +lor.end.critedge: ; preds = %entry + %d1.c = bitcast i64* %data to i32*, !dbg !42 + store i32 2, i32* %d1.c, align 8, !dbg !43, !tbaa !44 + br label %lor.end, !dbg !48 + +lor.end: ; preds = %lor.end.critedge, %cond.false + %6 = phi i32 [ %phitmp, %cond.false ], [ 1, %lor.end.critedge ] + %d2 = getelementptr inbounds %struct.data_t, %struct.data_t* %tmpcast, i64 0, i32 1, !dbg !49 + store i32 %6, i32* %d2, align 4, !dbg !50, !tbaa !51 + call void @output(i8* nonnull %2) #5, !dbg !52 + call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %2) #5, !dbg !53 + ret void, !dbg !53 +} + +; CHECK: ldxw r[[LOAD1:[0-9]+]], [r{{[0-9]+}} + 4] +; CHECK: and64 r[[LOAD1]], 65536 +; CHECK: ldxw r[[LOAD2:[0-9]+]], [r{{[0-9]+}} + 4] +; CHECK: and64 r[[LOAD2]], 32768 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.info_ts(%struct.info_t*, i32 immarg, i32 immarg) #3 + +declare !dbg !4 dso_local void @output(i8*) local_unnamed_addr #4 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable willreturn } +attributes #2 = { argmemonly nounwind willreturn } +attributes #3 = { nounwind readnone } +attributes #4 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #5 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9, !10} +!llvm.ident = !{!11} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 5884aae58f56786475bbc0f13ad8bd35f7f1ce69)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{} +!3 = !{!4} +!4 = !DISubprogram(name: "output", scope: !1, file: !1, line: 10, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{null, !7} +!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!8 = !{i32 7, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"wchar_size", i32 4} +!11 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 5884aae58f56786475bbc0f13ad8bd35f7f1ce69)"} +!12 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 11, type: !13, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !21) +!13 = !DISubroutineType(types: !14) +!14 = !{null, !15} +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "info_t", file: !1, line: 5, size: 64, elements: !17) +!17 = !{!18, !20} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "pid", scope: !16, file: !1, line: 6, baseType: !19, size: 32) +!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!20 = !DIDerivedType(tag: DW_TAG_member, name: "flags", scope: !16, file: !1, line: 7, baseType: !19, size: 32, offset: 32) +!21 = !{!22, !23, !24} +!22 = !DILocalVariable(name: "args", arg: 1, scope: !12, file: !1, line: 11, type: !15) +!23 = !DILocalVariable(name: "is_mask2", scope: !12, file: !1, line: 12, type: !19) +!24 = !DILocalVariable(name: "data", scope: !12, file: !1, line: 13, type: !25) +!25 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "data_t", file: !1, line: 1, size: 64, elements: !26) +!26 = !{!27, !28} +!27 = !DIDerivedType(tag: DW_TAG_member, name: "d1", scope: !25, file: !1, line: 2, baseType: !19, size: 32) +!28 = !DIDerivedType(tag: DW_TAG_member, name: "d2", scope: !25, file: !1, line: 3, baseType: !19, size: 32, offset: 32) +!29 = !DILocation(line: 0, scope: !12) +!30 = !DILocation(line: 12, column: 24, scope: !12) +!31 = !{!32, !33, i64 4} +!32 = !{!"info_t", !33, i64 0, !33, i64 4} +!33 = !{!"int", !34, i64 0} +!34 = !{!"omnipotent char", !35, i64 0} +!35 = !{!"Simple C/C++ TBAA"} +!36 = !DILocation(line: 12, column: 30, scope: !12) +!37 = !DILocation(line: 13, column: 3, scope: !12) +!38 = !DILocation(line: 13, column: 17, scope: !12) +!39 = !DILocation(line: 15, column: 13, scope: !12) +!40 = !DILocation(line: 15, column: 34, scope: !12) +!41 = !{!32, !33, i64 0} +!42 = !DILocation(line: 15, column: 8, scope: !12) +!43 = !DILocation(line: 15, column: 11, scope: !12) +!44 = !{!45, !33, i64 0} +!45 = !{!"data_t", !33, i64 0, !33, i64 4} +!46 = !DILocation(line: 16, column: 33, scope: !12) +!47 = !DILocation(line: 16, column: 39, scope: !12) +!48 = !DILocation(line: 16, column: 23, scope: !12) +!49 = !DILocation(line: 16, column: 8, scope: !12) +!50 = !DILocation(line: 16, column: 11, scope: !12) +!51 = !{!45, !33, i64 4} +!52 = !DILocation(line: 17, column: 3, scope: !12) +!53 = !DILocation(line: 18, column: 1, scope: !12) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-access-str.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-access-str.ll new file mode 100644 index 00000000000000..3457b95be2c422 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-access-str.ll @@ -0,0 +1,100 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source code: +; struct s { int a; int b; }; +; struct t { int c; int d; }; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const void *addr1, const void *addr2); +; int test(struct s *arg1, struct t *arg2) { +; return get_value(_(&arg1->b), _(&arg2->d)); +; } +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s = type { i32, i32 } +%struct.t = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.s* %arg1, %struct.t* %arg2) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.s* %arg1, metadata !22, metadata !DIExpression()), !dbg !24 + call void @llvm.dbg.value(metadata %struct.t* %arg2, metadata !23, metadata !DIExpression()), !dbg !24 + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s* elementtype(%struct.s) %arg1, i32 1, i32 1), !dbg !25, !llvm.preserve.access.index !12 + %1 = bitcast i32* %0 to i8*, !dbg !25 + %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ts(%struct.t* elementtype(%struct.t) %arg2, i32 1, i32 1), !dbg !26, !llvm.preserve.access.index !17 + %3 = bitcast i32* %2 to i8*, !dbg !26 + %call = tail call i32 @get_value(i8* %1, i8* %3) #4, !dbg !27 + ret i32 %call, !dbg !28 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK: .ascii ".text" # string offset=[[SEC_INDEX:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .ascii "0:1" # string offset=[[ACCESS_STR:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .section .BTF.ext,"",@progbits +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long [[SEC_INDEX]] # Field reloc section string offset=[[SEC_INDEX]] +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long {{[0-9]+}} +; CHECK-NEXT: .long [[ACCESS_STR]] +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long {{[0-9]+}} +; CHECK-NEXT: .long [[ACCESS_STR]] +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i8*, i8*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ts(%struct.t*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/core-bugs") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !21) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11, !16} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 1, size: 64, elements: !13) +!13 = !{!14, !15} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !12, file: !1, line: 1, baseType: !10, size: 32) +!15 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !12, file: !1, line: 1, baseType: !10, size: 32, offset: 32) +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64) +!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !1, line: 2, size: 64, elements: !18) +!18 = !{!19, !20} +!19 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !17, file: !1, line: 2, baseType: !10, size: 32) +!20 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !17, file: !1, line: 2, baseType: !10, size: 32, offset: 32) +!21 = !{!22, !23} +!22 = !DILocalVariable(name: "arg1", arg: 1, scope: !7, file: !1, line: 5, type: !11) +!23 = !DILocalVariable(name: "arg2", arg: 2, scope: !7, file: !1, line: 5, type: !16) +!24 = !DILocation(line: 0, scope: !7) +!25 = !DILocation(line: 6, column: 20, scope: !7) +!26 = !DILocation(line: 6, column: 33, scope: !7) +!27 = !DILocation(line: 6, column: 10, scope: !7) +!28 = !DILocation(line: 6, column: 3, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-basic.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-basic.ll new file mode 100644 index 00000000000000..71d9e2124090f7 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-basic.ll @@ -0,0 +1,188 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct sk_buff { +; int i; +; struct net_device *dev; +; }; +; #define _(x) (__builtin_preserve_access_index(x)) +; static int (*bpf_probe_read)(void *dst, int size, void *unsafe_ptr) +; = (void *) 4; +; +; int bpf_prog(struct sk_buff *ctx) { +; struct net_device *dev = 0; +; bpf_probe_read(&dev, sizeof(dev), _(&ctx->dev)); +; return dev != 0; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.sk_buff = type { i32, %struct.net_device* } +%struct.net_device = type opaque + +; Function Attrs: nounwind +define dso_local i32 @bpf_prog(%struct.sk_buff*) local_unnamed_addr #0 !dbg !15 { + %2 = alloca %struct.net_device*, align 8 + call void @llvm.dbg.value(metadata %struct.sk_buff* %0, metadata !26, metadata !DIExpression()), !dbg !28 + %3 = bitcast %struct.net_device** %2 to i8*, !dbg !29 + call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %3) #4, !dbg !29 + call void @llvm.dbg.value(metadata %struct.net_device* null, metadata !27, metadata !DIExpression()), !dbg !28 + store %struct.net_device* null, %struct.net_device** %2, align 8, !dbg !30, !tbaa !31 + %4 = tail call %struct.net_device** @llvm.preserve.struct.access.index.p0p0s_struct.net_devices.p0s_struct.sk_buffs(%struct.sk_buff* elementtype(%struct.sk_buff) %0, i32 1, i32 1), !dbg !35, !llvm.preserve.access.index !19 + %5 = bitcast %struct.net_device** %4 to i8*, !dbg !35 + %6 = call i32 inttoptr (i64 4 to i32 (i8*, i32, i8*)*)(i8* nonnull %3, i32 8, i8* %5) #4, !dbg !36 + %7 = load %struct.net_device*, %struct.net_device** %2, align 8, !dbg !37, !tbaa !31 + call void @llvm.dbg.value(metadata %struct.net_device* %7, metadata !27, metadata !DIExpression()), !dbg !28 + %8 = icmp ne %struct.net_device* %7, null, !dbg !38 + %9 = zext i1 %8 to i32, !dbg !38 + call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %3) #4, !dbg !39 + ret i32 %9, !dbg !40 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 120 +; CHECK-NEXT: .long 120 +; CHECK-NEXT: .long 90 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 2) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 64 # 0x40 +; CHECK-NEXT: .long 15 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 19 # BTF_KIND_FWD(id = 5) +; CHECK-NEXT: .long 117440512 # 0x7000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 6) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 30 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 34 # BTF_KIND_FUNC(id = 7) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "sk_buff" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 105 # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "dev" # string offset=11 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=15 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "net_device" # string offset=19 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "ctx" # string offset=30 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "bpf_prog" # string offset=34 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=43 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/llvm/test.c" # string offset=49 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "0:1" # string offset=86 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 124 +; CHECK-NEXT: .long 144 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 8 # FuncInfo + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 43 # Field reloc section string offset=43 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 86 +; CHECK-NEXT: .long 0 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone +declare %struct.net_device** @llvm.preserve.struct.access.index.p0p0s_struct.net_devices.p0s_struct.sk_buffs(%struct.sk_buff*, i32 immarg, i32 immarg) #2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 (trunk 360739) (llvm/trunk 360747)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm") +!2 = !{} +!3 = !{!4} +!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression()) +!5 = distinct !DIGlobalVariable(name: "bpf_probe_read", scope: !0, file: !1, line: 6, type: !6, isLocal: true, isDefinition: true) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !10, !9, !10} +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 9.0.0 (trunk 360739) (llvm/trunk 360747)"} +!15 = distinct !DISubprogram(name: "bpf_prog", scope: !1, file: !1, line: 9, type: !16, scopeLine: 9, flags: DIFlagPrototyped, isLocal: false, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !25) +!16 = !DISubroutineType(types: !17) +!17 = !{!9, !18} +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !1, line: 1, size: 128, elements: !20) +!20 = !{!21, !22} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !19, file: !1, line: 2, baseType: !9, size: 32) +!22 = !DIDerivedType(tag: DW_TAG_member, name: "dev", scope: !19, file: !1, line: 3, baseType: !23, size: 64, offset: 64) +!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !24, size: 64) +!24 = !DICompositeType(tag: DW_TAG_structure_type, name: "net_device", file: !1, line: 3, flags: DIFlagFwdDecl) +!25 = !{!26, !27} +!26 = !DILocalVariable(name: "ctx", arg: 1, scope: !15, file: !1, line: 9, type: !18) +!27 = !DILocalVariable(name: "dev", scope: !15, file: !1, line: 10, type: !23) +!28 = !DILocation(line: 0, scope: !15) +!29 = !DILocation(line: 10, column: 3, scope: !15) +!30 = !DILocation(line: 10, column: 22, scope: !15) +!31 = !{!32, !32, i64 0} +!32 = !{!"any pointer", !33, i64 0} +!33 = !{!"omnipotent char", !34, i64 0} +!34 = !{!"Simple C/C++ TBAA"} +!35 = !DILocation(line: 11, column: 37, scope: !15) +!36 = !DILocation(line: 11, column: 3, scope: !15) +!37 = !DILocation(line: 12, column: 10, scope: !15) +!38 = !DILocation(line: 12, column: 14, scope: !15) +!39 = !DILocation(line: 13, column: 1, scope: !15) +!40 = !DILocation(line: 12, column: 3, scope: !15) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-array-1.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-array-1.ll new file mode 100644 index 00000000000000..c446ae45ee6edd --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-array-1.ll @@ -0,0 +1,129 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct v1 {int a; int b;}; +; typedef struct v1 __v1; +; typedef __v1 arr[4]; +; struct v3 { char c; int d[100]; }; +; #define _(x) (__builtin_preserve_access_index(x)) +; #define cast_to_arr(x) ((arr *)(x)) +; int get_value(const int *arg); +; int test(struct v3 *arg) { +; return get_value(_(&cast_to_arr(&arg->d[0])[0][2].b)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i8, [100 x i32] } +%struct.v1 = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !22 { +entry: + call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !32, metadata !DIExpression()), !dbg !33 + %0 = tail call [100 x i32]* @llvm.preserve.struct.access.index.p0a100i32.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %arg, i32 1, i32 1), !dbg !34, !llvm.preserve.access.index !26 + %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a100i32([100 x i32]* elementtype([100 x i32]) %0, i32 1, i32 0), !dbg !34, !llvm.preserve.access.index !15 + %2 = bitcast i32* %1 to [4 x %struct.v1]*, !dbg !34 + %3 = tail call [4 x %struct.v1]* @llvm.preserve.array.access.index.p0a4s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]* elementtype([4 x %struct.v1]) %2, i32 0, i32 0), !dbg !34, !llvm.preserve.access.index !4 + %4 = tail call %struct.v1* @llvm.preserve.array.access.index.p0s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]* elementtype([4 x %struct.v1]) %3, i32 1, i32 2), !dbg !34, !llvm.preserve.access.index !5 + %5 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1* elementtype(%struct.v1) %4, i32 1, i32 1), !dbg !34, !llvm.preserve.access.index !8 + %call = tail call i32 @get_value(i32* %5) #4, !dbg !35 + ret i32 %call, !dbg !36 +} + +; CHECK: mov64 r2, 4 +; CHECK: add64 r1, r2 +; CHECK: mov64 r2, 20 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) +; CHECK: .long 100 # BTF_KIND_STRUCT(id = [[TID2:[0-9]+]]) + +; CHECK: .ascii "v3" # string offset=1 +; CHECK: .ascii ".text" # string offset=46 +; CHECK: .ascii "0:1:0" # string offset=52 +; CHECK: .ascii "2:1" # string offset=107 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 46 # Field reloc section string offset=46 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID2]] +; CHECK-NEXT: .long 107 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare [100 x i32]* @llvm.preserve.struct.access.index.p0a100i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.array.access.index.p0i32.p0a100i32([100 x i32]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare [4 x %struct.v1]* @llvm.preserve.array.access.index.p0a4s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare %struct.v1* @llvm.preserve.array.access.index.p0s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1*, i32, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!18, !19, !20} +!llvm.ident = !{!21} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4, !15, !5} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "arr", file: !1, line: 3, baseType: !6) +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 256, elements: !13) +!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !8) +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v1", file: !1, line: 1, size: 64, elements: !9) +!9 = !{!10, !12} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !1, line: 1, baseType: !11, size: 32) +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !1, line: 1, baseType: !11, size: 32, offset: 32) +!13 = !{!14} +!14 = !DISubrange(count: 4) +!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, size: 3200, elements: !16) +!16 = !{!17} +!17 = !DISubrange(count: 100) +!18 = !{i32 2, !"Dwarf Version", i32 4} +!19 = !{i32 2, !"Debug Info Version", i32 3} +!20 = !{i32 1, !"wchar_size", i32 4} +!21 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!22 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 8, type: !23, scopeLine: 8, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !31) +!23 = !DISubroutineType(types: !24) +!24 = !{!11, !25} +!25 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !26, size: 64) +!26 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 4, size: 3232, elements: !27) +!27 = !{!28, !30} +!28 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !26, file: !1, line: 4, baseType: !29, size: 8) +!29 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!30 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !26, file: !1, line: 4, baseType: !15, size: 3200, offset: 32) +!31 = !{!32} +!32 = !DILocalVariable(name: "arg", arg: 1, scope: !22, file: !1, line: 8, type: !25) +!33 = !DILocation(line: 0, scope: !22) +!34 = !DILocation(line: 9, column: 20, scope: !22) +!35 = !DILocation(line: 9, column: 10, scope: !22) +!36 = !DILocation(line: 9, column: 3, scope: !22) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-array-2.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-array-2.ll new file mode 100644 index 00000000000000..e2a407f22c4d5c --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-array-2.ll @@ -0,0 +1,136 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct v1 {int a; int b;}; +; typedef struct v1 __v1; +; typedef __v1 arr[4][4]; +; struct v3 { char c; int d[100]; }; +; #define _(x) (__builtin_preserve_access_index(x)) +; #define cast_to_arr(x) ((arr *)(x)) +; int get_value(const int *arg); +; int test(struct v3 *arg) { +; return get_value(_(&cast_to_arr(&arg->d[0])[0][2][3].b)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i8, [100 x i32] } +%struct.v1 = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !24 { +entry: + call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !34, metadata !DIExpression()), !dbg !35 + %0 = tail call [100 x i32]* @llvm.preserve.struct.access.index.p0a100i32.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %arg, i32 1, i32 1), !dbg !36, !llvm.preserve.access.index !28 + %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a100i32([100 x i32]* elementtype([100 x i32]) %0, i32 1, i32 0), !dbg !36, !llvm.preserve.access.index !15 + %2 = bitcast i32* %1 to [4 x [4 x %struct.v1]]*, !dbg !36 + %3 = tail call [4 x [4 x %struct.v1]]* @llvm.preserve.array.access.index.p0a4a4s_struct.v1s.p0a4a4s_struct.v1s([4 x [4 x %struct.v1]]* elementtype([4 x [4 x %struct.v1]]) %2, i32 0, i32 0), !dbg !36, !llvm.preserve.access.index !4 + %4 = tail call [4 x %struct.v1]* @llvm.preserve.array.access.index.p0a4s_struct.v1s.p0a4a4s_struct.v1s([4 x [4 x %struct.v1]]* elementtype([4 x [4 x %struct.v1]]) %3, i32 1, i32 2), !dbg !36, !llvm.preserve.access.index !5 + %5 = tail call %struct.v1* @llvm.preserve.array.access.index.p0s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]* elementtype([4 x %struct.v1]) %4, i32 1, i32 3), !dbg !36, !llvm.preserve.access.index !18 + %6 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1* elementtype(%struct.v1) %5, i32 1, i32 1), !dbg !36, !llvm.preserve.access.index !8 + %call = tail call i32 @get_value(i32* %6) #4, !dbg !37 + ret i32 %call, !dbg !38 +} + +; CHECK: mov64 r2, 4 +; CHECK: add64 r1, r2 +; CHECK: mov64 r2, 92 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) +; CHECK: .long 100 # BTF_KIND_STRUCT(id = [[TID2:[0-9]+]]) + +; CHECK: .ascii "v3" # string offset=1 +; CHECK: .ascii ".text" # string offset=46 +; CHECK: .ascii "0:1:0" # string offset=52 +; CHECK: .ascii "v1" # string offset=100 +; CHECK: .ascii "11:1" # string offset=107 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 46 # Field reloc section string offset=46 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID2]] +; CHECK-NEXT: .long 107 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare [100 x i32]* @llvm.preserve.struct.access.index.p0a100i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.array.access.index.p0i32.p0a100i32([100 x i32]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare [4 x [4 x %struct.v1]]* @llvm.preserve.array.access.index.p0a4a4s_struct.v1s.p0a4a4s_struct.v1s([4 x [4 x %struct.v1]]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare [4 x %struct.v1]* @llvm.preserve.array.access.index.p0a4s_struct.v1s.p0a4a4s_struct.v1s([4 x [4 x %struct.v1]]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare %struct.v1* @llvm.preserve.array.access.index.p0s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1*, i32, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!20, !21, !22} +!llvm.ident = !{!23} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4, !15, !5, !18} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "arr", file: !1, line: 3, baseType: !6) +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 1024, elements: !13) +!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !8) +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v1", file: !1, line: 1, size: 64, elements: !9) +!9 = !{!10, !12} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !1, line: 1, baseType: !11, size: 32) +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !1, line: 1, baseType: !11, size: 32, offset: 32) +!13 = !{!14, !14} +!14 = !DISubrange(count: 4) +!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, size: 3200, elements: !16) +!16 = !{!17} +!17 = !DISubrange(count: 100) +!18 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 256, elements: !19) +!19 = !{!14} +!20 = !{i32 2, !"Dwarf Version", i32 4} +!21 = !{i32 2, !"Debug Info Version", i32 3} +!22 = !{i32 1, !"wchar_size", i32 4} +!23 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!24 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 8, type: !25, scopeLine: 8, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !33) +!25 = !DISubroutineType(types: !26) +!26 = !{!11, !27} +!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !28, size: 64) +!28 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 4, size: 3232, elements: !29) +!29 = !{!30, !32} +!30 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !28, file: !1, line: 4, baseType: !31, size: 8) +!31 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!32 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !28, file: !1, line: 4, baseType: !15, size: 3200, offset: 32) +!33 = !{!34} +!34 = !DILocalVariable(name: "arg", arg: 1, scope: !24, file: !1, line: 8, type: !27) +!35 = !DILocation(line: 0, scope: !24) +!36 = !DILocation(line: 9, column: 20, scope: !24) +!37 = !DILocation(line: 9, column: 10, scope: !24) +!38 = !DILocation(line: 9, column: 3, scope: !24) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-struct-1.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-struct-1.ll new file mode 100644 index 00000000000000..6f8dbd215dfd2f --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-struct-1.ll @@ -0,0 +1,117 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct v1 { int a; int b; }; +; struct v2 { int c; int d; }; +; struct v3 { char c; struct v2 d; }; +; #define _(x) (__builtin_preserve_access_index(x)) +; #define cast_to_v1(x) ((struct v1 *)(x)) +; int get_value(const int *arg); +; int test(struct v3 *arg) { +; return get_value(_(&cast_to_v1(&arg->d)->b)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i8, %struct.v2 } +%struct.v2 = type { i32, i32 } +%struct.v1 = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !14 { +entry: + call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !28, metadata !DIExpression()), !dbg !29 + %0 = tail call %struct.v2* @llvm.preserve.struct.access.index.p0s_struct.v2s.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %arg, i32 1, i32 1), !dbg !30, !llvm.preserve.access.index !18 + %1 = bitcast %struct.v2* %0 to %struct.v1*, !dbg !30 + %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1* elementtype(%struct.v1) %1, i32 1, i32 1), !dbg !30, !llvm.preserve.access.index !5 + %call = tail call i32 @get_value(i32* %2) #4, !dbg !31 + ret i32 %call, !dbg !32 +} + +; CHECK: mov64 r2, 4 +; CHECK: add64 r1, r2 +; CHECK: mov64 r2, 4 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = [[V3_TID:[0-9]+]]) +; CHECK: .long 81 # BTF_KIND_STRUCT(id = [[V1_TID:[0-9]+]]) + +; CHECK: .ascii "v3" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK: .ascii ".text" # string offset=[[SEC_STR:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .ascii "0:1" # string offset=[[ACCESS_STR:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .ascii "v1" # string offset=81 +; CHECK-NEXT: .byte 0 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long [[SEC_STR]] # Field reloc section string offset=[[SEC_STR]] +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[V3_TID]] +; CHECK-NEXT: .long [[ACCESS_STR]] +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[V1_TID]] +; CHECK-NEXT: .long [[ACCESS_STR]] +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare %struct.v2* @llvm.preserve.struct.access.index.p0s_struct.v2s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1*, i32, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v1", file: !1, line: 1, size: 64, elements: !6) +!6 = !{!7, !9} +!7 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !5, file: !1, line: 1, baseType: !8, size: 32) +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!9 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !5, file: !1, line: 1, baseType: !8, size: 32, offset: 32) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!14 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 7, type: !15, scopeLine: 7, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !27) +!15 = !DISubroutineType(types: !16) +!16 = !{!8, !17} +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64) +!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 3, size: 96, elements: !19) +!19 = !{!20, !22} +!20 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !18, file: !1, line: 3, baseType: !21, size: 8) +!21 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!22 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !18, file: !1, line: 3, baseType: !23, size: 64, offset: 32) +!23 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v2", file: !1, line: 2, size: 64, elements: !24) +!24 = !{!25, !26} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !23, file: !1, line: 2, baseType: !8, size: 32) +!26 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !23, file: !1, line: 2, baseType: !8, size: 32, offset: 32) +!27 = !{!28} +!28 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 7, type: !17) +!29 = !DILocation(line: 0, scope: !14) +!30 = !DILocation(line: 8, column: 20, scope: !14) +!31 = !DILocation(line: 8, column: 10, scope: !14) +!32 = !DILocation(line: 8, column: 3, scope: !14) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-struct-2.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-struct-2.ll new file mode 100644 index 00000000000000..68d7a65eb05689 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-struct-2.ll @@ -0,0 +1,122 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct v1 { int a; int b; }; +; typedef struct v1 __v1; +; struct v2 { int c; int d; }; +; typedef struct v2 __v2; +; struct v3 { char c; volatile const __v2 d; }; +; typedef struct v3 __v3; +; #define _(x) (__builtin_preserve_access_index(x)) +; #define cast_to_v1(x) ((__v1 *)(x)) +; int get_value(const int *arg); +; int test(__v3 *arg) { +; return get_value(_(&cast_to_v1(&arg->d)->b)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i8, %struct.v2 } +%struct.v2 = type { i32, i32 } +%struct.v1 = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !15 { +entry: + call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !33, metadata !DIExpression()), !dbg !34 + %0 = tail call %struct.v2* @llvm.preserve.struct.access.index.p0s_struct.v2s.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %arg, i32 1, i32 1), !dbg !35, !llvm.preserve.access.index !20 + %1 = bitcast %struct.v2* %0 to %struct.v1*, !dbg !35 + %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1* elementtype(%struct.v1) %1, i32 1, i32 1), !dbg !35, !llvm.preserve.access.index !6 + %call = tail call i32 @get_value(i32* %2) #4, !dbg !36 + ret i32 %call, !dbg !37 +} + +; CHECK: mov64 r2, 4 +; CHECK: add64 r1, r2 +; CHECK: mov64 r2, 4 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) +; CHECK: .long 91 # BTF_KIND_STRUCT(id = [[TID2:[0-9]+]]) + +; CHECK: .ascii "v3" # string offset=6 +; CHECK: .ascii ".text" # string offset=39 +; CHECK: .ascii "0:1" # string offset=45 +; CHECK: .ascii "v1" # string offset=91 + + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 39 # Field reloc section string offset=39 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 45 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID2]] +; CHECK-NEXT: .long 45 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare %struct.v2* @llvm.preserve.struct.access.index.p0s_struct.v2s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1*, i32, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !6) +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v1", file: !1, line: 1, size: 64, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32, offset: 32) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!15 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 10, type: !16, scopeLine: 10, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !32) +!16 = !DISubroutineType(types: !17) +!17 = !{!9, !18} +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!19 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 6, baseType: !20) +!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 5, size: 96, elements: !21) +!21 = !{!22, !24} +!22 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !20, file: !1, line: 5, baseType: !23, size: 8) +!23 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!24 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !20, file: !1, line: 5, baseType: !25, size: 64, offset: 32) +!25 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !26) +!26 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !27) +!27 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v2", file: !1, line: 4, baseType: !28) +!28 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v2", file: !1, line: 3, size: 64, elements: !29) +!29 = !{!30, !31} +!30 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !28, file: !1, line: 3, baseType: !9, size: 32) +!31 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !28, file: !1, line: 3, baseType: !9, size: 32, offset: 32) +!32 = !{!33} +!33 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 10, type: !18) +!34 = !DILocation(line: 0, scope: !15) +!35 = !DILocation(line: 11, column: 20, scope: !15) +!36 = !DILocation(line: 11, column: 10, scope: !15) +!37 = !DILocation(line: 11, column: 3, scope: !15) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-struct-3.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-struct-3.ll new file mode 100644 index 00000000000000..907700d352b8f4 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-struct-3.ll @@ -0,0 +1,121 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct v1 { int a; int b; }; +; typedef struct v1 __v1; +; typedef int __int; +; struct v3 { char c; __int d[40]; }; +; typedef struct v3 __v3; +; #define _(x) (__builtin_preserve_access_index(x)) +; #define cast_to_v1(x) ((__v1 *)(x)) +; int get_value(const int *arg); +; int test(__v3 *arg) { +; return get_value(_(&cast_to_v1(&arg->d[4])->b)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i8, [40 x i32] } +%struct.v1 = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !19 { +entry: + call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !30, metadata !DIExpression()), !dbg !31 + %0 = tail call [40 x i32]* @llvm.preserve.struct.access.index.p0a40i32.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %arg, i32 1, i32 1), !dbg !32, !llvm.preserve.access.index !24 + %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a40i32([40 x i32]* elementtype([40 x i32]) %0, i32 1, i32 4), !dbg !32, !llvm.preserve.access.index !11 + %2 = bitcast i32* %1 to %struct.v1*, !dbg !32 + %3 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1* elementtype(%struct.v1) %2, i32 1, i32 1), !dbg !32, !llvm.preserve.access.index !6 + %call = tail call i32 @get_value(i32* %3) #4, !dbg !33 + ret i32 %call, !dbg !34 +} + +; CHECK: mov64 r2, 20 +; CHECK: add64 r1, r2 +; CHECK: mov64 r2, 4 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) +; CHECK: .long 111 # BTF_KIND_STRUCT(id = [[TID2:[0-9]+]]) + +; CHECK: .ascii "v3" # string offset=6 +; CHECK: .ascii ".text" # string offset=57 +; CHECK: .ascii "0:1:4" # string offset=63 +; CHECK: .ascii "v1" # string offset=111 +; CHECK: .ascii "0:1" # string offset=118 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 57 # Field reloc section string offset=57 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 63 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID2]] +; CHECK-NEXT: .long 118 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare [40 x i32]* @llvm.preserve.struct.access.index.p0a40i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.array.access.index.p0i32.p0a40i32([40 x i32]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1*, i32, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!15, !16, !17} +!llvm.ident = !{!18} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4, !11} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !6) +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v1", file: !1, line: 1, size: 64, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32, offset: 32) +!11 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 1280, elements: !13) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 3, baseType: !9) +!13 = !{!14} +!14 = !DISubrange(count: 40) +!15 = !{i32 2, !"Dwarf Version", i32 4} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{i32 1, !"wchar_size", i32 4} +!18 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!19 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 9, type: !20, scopeLine: 9, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !29) +!20 = !DISubroutineType(types: !21) +!21 = !{!9, !22} +!22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !23, size: 64) +!23 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 5, baseType: !24) +!24 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 4, size: 1312, elements: !25) +!25 = !{!26, !28} +!26 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !24, file: !1, line: 4, baseType: !27, size: 8) +!27 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!28 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !24, file: !1, line: 4, baseType: !11, size: 1280, offset: 32) +!29 = !{!30} +!30 = !DILocalVariable(name: "arg", arg: 1, scope: !19, file: !1, line: 9, type: !22) +!31 = !DILocation(line: 0, scope: !19) +!32 = !DILocation(line: 10, column: 20, scope: !19) +!33 = !DILocation(line: 10, column: 10, scope: !19) +!34 = !DILocation(line: 10, column: 3, scope: !19) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-union-1.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-union-1.ll new file mode 100644 index 00000000000000..e6f6a8c3b9039d --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-union-1.ll @@ -0,0 +1,122 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; union v1 { int a; int b; }; +; typedef union v1 __v1; +; union v2 { int c; int d; }; +; typedef union v2 __v2; +; union v3 { char c; volatile const __v2 d; }; +; typedef union v3 __v3; +; #define _(x) (__builtin_preserve_access_index(x)) +; #define cast_to_v1(x) ((__v1 *)(x)) +; int get_value(const int *arg); +; int test(__v3 *arg) { +; return get_value(_(&cast_to_v1(&arg->d)->b)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.v3 = type { %union.v2 } +%union.v2 = type { i32 } +%union.v1 = type { i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%union.v3* %arg) local_unnamed_addr #0 !dbg !15 { +entry: + call void @llvm.dbg.value(metadata %union.v3* %arg, metadata !33, metadata !DIExpression()), !dbg !34 + %0 = tail call %union.v3* @llvm.preserve.union.access.index.p0s_union.v3s.p0s_union.v3s(%union.v3* %arg, i32 1), !dbg !35, !llvm.preserve.access.index !20 + %1 = bitcast %union.v3* %0 to %union.v1*, !dbg !35 + %2 = tail call %union.v1* @llvm.preserve.union.access.index.p0s_union.v1s.p0s_union.v1s(%union.v1* %1, i32 1), !dbg !35, !llvm.preserve.access.index !6 + %b = getelementptr inbounds %union.v1, %union.v1* %2, i64 0, i32 0, !dbg !35 + %call = tail call i32 @get_value(i32* %b) #4, !dbg !36 + ret i32 %call, !dbg !37 +} + +; CHECK: mov64 r2, 0 +; CHECK: add64 r1, r2 +; CHECK: mov64 r2, 0 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 6 # BTF_KIND_UNION(id = [[TID1:[0-9]+]]) +; CHECK: .long 91 # BTF_KIND_UNION(id = [[TID2:[0-9]+]]) + +; CHECK: .ascii "v3" # string offset=6 +; CHECK: .ascii ".text" # string offset=39 +; CHECK: .ascii "0:1" # string offset=45 +; CHECK: .ascii "v1" # string offset=91 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 39 # Field reloc section string offset=39 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 45 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID2]] +; CHECK-NEXT: .long 45 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare %union.v3* @llvm.preserve.union.access.index.p0s_union.v3s.p0s_union.v3s(%union.v3*, i32) #2 + +; Function Attrs: nounwind readnone +declare %union.v1* @llvm.preserve.union.access.index.p0s_union.v1s.p0s_union.v1s(%union.v1*, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !6) +!6 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "v1", file: !1, line: 1, size: 32, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!15 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 10, type: !16, scopeLine: 10, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !32) +!16 = !DISubroutineType(types: !17) +!17 = !{!9, !18} +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!19 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 6, baseType: !20) +!20 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "v3", file: !1, line: 5, size: 32, elements: !21) +!21 = !{!22, !24} +!22 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !20, file: !1, line: 5, baseType: !23, size: 8) +!23 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!24 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !20, file: !1, line: 5, baseType: !25, size: 32) +!25 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !26) +!26 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !27) +!27 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v2", file: !1, line: 4, baseType: !28) +!28 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "v2", file: !1, line: 3, size: 32, elements: !29) +!29 = !{!30, !31} +!30 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !28, file: !1, line: 3, baseType: !9, size: 32) +!31 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !28, file: !1, line: 3, baseType: !9, size: 32) +!32 = !{!33} +!33 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 10, type: !18) +!34 = !DILocation(line: 0, scope: !15) +!35 = !DILocation(line: 11, column: 20, scope: !15) +!36 = !DILocation(line: 11, column: 10, scope: !15) +!37 = !DILocation(line: 11, column: 3, scope: !15) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-union-2.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-union-2.ll new file mode 100644 index 00000000000000..d64dbd60e24976 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-cast-union-2.ll @@ -0,0 +1,123 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; union v1 { int a; int b; }; +; typedef union v1 __v1; +; typedef int __int; +; union v3 { char c; __int d[40]; }; +; typedef union v3 __v3; +; #define _(x) (__builtin_preserve_access_index(x)) +; #define cast_to_v1(x) ((__v1 *)(x)) +; int get_value(const int *arg); +; int test(__v3 *arg) { +; return get_value(_(&cast_to_v1(&arg->d[4])->b)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.v3 = type { [40 x i32] } +%union.v1 = type { i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%union.v3* %arg) local_unnamed_addr #0 !dbg !19 { +entry: + call void @llvm.dbg.value(metadata %union.v3* %arg, metadata !30, metadata !DIExpression()), !dbg !31 + %0 = tail call %union.v3* @llvm.preserve.union.access.index.p0s_union.v3s.p0s_union.v3s(%union.v3* %arg, i32 1), !dbg !32, !llvm.preserve.access.index !24 + %d = getelementptr inbounds %union.v3, %union.v3* %0, i64 0, i32 0, !dbg !32 + %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a40i32([40 x i32]* elementtype([40 x i32]) %d, i32 1, i32 4), !dbg !32, !llvm.preserve.access.index !11 + %2 = bitcast i32* %1 to %union.v1*, !dbg !32 + %3 = tail call %union.v1* @llvm.preserve.union.access.index.p0s_union.v1s.p0s_union.v1s(%union.v1* %2, i32 1), !dbg !32, !llvm.preserve.access.index !6 + %b = getelementptr inbounds %union.v1, %union.v1* %3, i64 0, i32 0, !dbg !32 + %call = tail call i32 @get_value(i32* %b) #4, !dbg !33 + ret i32 %call, !dbg !34 +} + +; CHECK: mov64 r2, 16 +; CHECK: add64 r1, r2 +; CHECK: mov64 r2, 0 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 6 # BTF_KIND_UNION(id = [[TID1:[0-9]+]]) +; CHECK: .long 111 # BTF_KIND_UNION(id = [[TID2:[0-9]+]]) + +; CHECK: .ascii "v3" # string offset=6 +; CHECK: .ascii ".text" # string offset=57 +; CHECK: .ascii "0:1:4" # string offset=63 +; CHECK: .ascii "v1" # string offset=111 +; CHECK: .ascii "0:1" # string offset=118 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 57 # Field reloc section string offset=57 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 63 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID2]] +; CHECK-NEXT: .long 118 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare %union.v3* @llvm.preserve.union.access.index.p0s_union.v3s.p0s_union.v3s(%union.v3*, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.array.access.index.p0i32.p0a40i32([40 x i32]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare %union.v1* @llvm.preserve.union.access.index.p0s_union.v1s.p0s_union.v1s(%union.v1*, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!15, !16, !17} +!llvm.ident = !{!18} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4, !11} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !6) +!6 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "v1", file: !1, line: 1, size: 32, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32) +!11 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 1280, elements: !13) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 3, baseType: !9) +!13 = !{!14} +!14 = !DISubrange(count: 40) +!15 = !{i32 2, !"Dwarf Version", i32 4} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{i32 1, !"wchar_size", i32 4} +!18 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!19 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 9, type: !20, scopeLine: 9, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !29) +!20 = !DISubroutineType(types: !21) +!21 = !{!9, !22} +!22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !23, size: 64) +!23 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 5, baseType: !24) +!24 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "v3", file: !1, line: 4, size: 1280, elements: !25) +!25 = !{!26, !28} +!26 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !24, file: !1, line: 4, baseType: !27, size: 8) +!27 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!28 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !24, file: !1, line: 4, baseType: !11, size: 1280) +!29 = !{!30} +!30 = !DILocalVariable(name: "arg", arg: 1, scope: !19, file: !1, line: 9, type: !22) +!31 = !DILocation(line: 0, scope: !19) +!32 = !DILocation(line: 10, column: 20, scope: !19) +!33 = !DILocation(line: 10, column: 10, scope: !19) +!34 = !DILocation(line: 10, column: 3, scope: !19) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-end-load.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-end-load.ll new file mode 100644 index 00000000000000..7a85f3101d0375 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-end-load.ll @@ -0,0 +1,86 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; +; Source Code: +; #define _(x) (__builtin_preserve_access_index(x)) +; struct s {int a; int b;}; +; int test(struct s *arg) { return *(const int *)_(&arg->b); } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s = type { i32, i32 } + +; Function Attrs: nounwind readonly +define dso_local i32 @test(%struct.s* readonly %arg) local_unnamed_addr #0 !dbg !11 { +entry: + call void @llvm.dbg.value(metadata %struct.s* %arg, metadata !20, metadata !DIExpression()), !dbg !21 + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s* elementtype(%struct.s) %arg, i32 1, i32 1), !dbg !22, !llvm.preserve.access.index !15 + %1 = load i32, i32* %0, align 4, !dbg !23, !tbaa !24 + ret i32 %1, !dbg !28 +} + +; CHECK-LABEL: test +; CHECK-ALU64: ldxw r0, [r1 + 4] +; CHECK-ALU32: ldxw w0, [r1 + 4] +; CHECK: exit +; +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 2) +; +; CHECK: .byte 115 # string offset=1 +; CHECK: .ascii ".text" # string offset=20 +; CHECK: .ascii "0:1" # string offset=26 +; +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 20 # Field reloc section string offset=20 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 0 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s*, i32, i32) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 6e353b4df3aa452ed4741a5e5caea02b1a876d8c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !6) +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 6e353b4df3aa452ed4741a5e5caea02b1a876d8c)"} +!11 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !12, scopeLine: 3, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !19) +!12 = !DISubroutineType(types: !13) +!13 = !{!6, !14} +!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !15, size: 64) +!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 2, size: 64, elements: !16) +!16 = !{!17, !18} +!17 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !15, file: !1, line: 2, baseType: !6, size: 32) +!18 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !15, file: !1, line: 2, baseType: !6, size: 32, offset: 32) +!19 = !{!20} +!20 = !DILocalVariable(name: "arg", arg: 1, scope: !11, file: !1, line: 3, type: !14) +!21 = !DILocation(line: 0, scope: !11) +!22 = !DILocation(line: 3, column: 48, scope: !11) +!23 = !DILocation(line: 3, column: 34, scope: !11) +!24 = !{!25, !25, i64 0} +!25 = !{!"int", !26, i64 0} +!26 = !{!"omnipotent char", !27, i64 0} +!27 = !{!"Simple C/C++ TBAA"} +!28 = !DILocation(line: 3, column: 27, scope: !11) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-end-ret.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-end-ret.ll new file mode 100644 index 00000000000000..8dffa10c7ebe49 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-end-ret.ll @@ -0,0 +1,81 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source Code: +; #define _(x) (__builtin_preserve_access_index(x)) +; struct s {int a; int b;}; +; const void *test(struct s *arg) { return _(&arg->b); } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s = type { i32, i32 } + +; Function Attrs: nounwind readnone +define dso_local i8* @test(%struct.s* readnone %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.s* %arg, metadata !19, metadata !DIExpression()), !dbg !20 + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s* elementtype(%struct.s) %arg, i32 1, i32 1), !dbg !21, !llvm.preserve.access.index !13 + %1 = bitcast i32* %0 to i8*, !dbg !21 + ret i8* %1, !dbg !22 +} + +; CHECK-LABEL: test +; CHECK: mov64 r0, r1 +; CHECK: mov64 r1, 4 +; CHECK: add64 r0, r1 +; CHECK: exit +; +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 2) +; +; CHECK: .byte 115 # string offset=1 +; CHECK: .ascii ".text" # string offset=20 +; CHECK: .ascii "0:1" # string offset=63 +; +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 20 # Field reloc section string offset=20 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 63 +; CHECK-NEXT: .long 0 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s*, i32, i32) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 6e353b4df3aa452ed4741a5e5caea02b1a876d8c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 6e353b4df3aa452ed4741a5e5caea02b1a876d8c)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !18) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !12} +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64) +!11 = !DIDerivedType(tag: DW_TAG_const_type, baseType: null) +!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64) +!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 2, size: 64, elements: !14) +!14 = !{!15, !17} +!15 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !13, file: !1, line: 2, baseType: !16, size: 32) +!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!17 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !13, file: !1, line: 2, baseType: !16, size: 32, offset: 32) +!18 = !{!19} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 3, type: !12) +!20 = !DILocation(line: 0, scope: !7) +!21 = !DILocation(line: 3, column: 42, scope: !7) +!22 = !DILocation(line: 3, column: 35, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-fieldinfo-1.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-fieldinfo-1.ll new file mode 100644 index 00000000000000..57df4ebe5c5c12 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-fieldinfo-1.ll @@ -0,0 +1,200 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK32 %s +; Source code: +; struct s { +; int a; +; int b1:9; +; int b2:4; +; }; +; enum { +; FIELD_BYTE_OFFSET = 0, +; FIELD_BYTE_SIZE, +; FIELD_EXISTENCE, +; FIELD_SIGNEDNESS, +; FIELD_LSHIFT_U64, +; FIELD_RSHIFT_U64, +; }; +; void bpf_probe_read(void *, unsigned, const void *); +; int field_read(struct s *arg) { +; unsigned long long ull; +; unsigned offset = __builtin_preserve_field_info(arg->b2, FIELD_BYTE_OFFSET); +; unsigned size = __builtin_preserve_field_info(arg->b2, FIELD_BYTE_SIZE); +; unsigned lshift; +; +; bpf_probe_read(&ull, size, (const void *)arg + offset); +; lshift = __builtin_preserve_field_info(arg->b2, FIELD_LSHIFT_U64); +; #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +; lshift = lshift + (size << 3) - 64; +; #endif +; ull <<= lshift; +; if (__builtin_preserve_field_info(arg->b2, FIELD_SIGNEDNESS)) +; return (long long)ull >> __builtin_preserve_field_info(arg->b2, FIELD_RSHIFT_U64); +; return ull >> __builtin_preserve_field_info(arg->b2, FIELD_RSHIFT_U64); +; } +; Compilation flag: +; clang -target bpfel -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s = type { i32, i16 } + +; Function Attrs: nounwind +define dso_local i32 @field_read(%struct.s* %arg) local_unnamed_addr #0 !dbg !20 { +entry: + %ull = alloca i64, align 8 + call void @llvm.dbg.value(metadata %struct.s* %arg, metadata !31, metadata !DIExpression()), !dbg !37 + %0 = bitcast i64* %ull to i8*, !dbg !38 + call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #5, !dbg !38 + %1 = tail call i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.ss(%struct.s* elementtype(%struct.s) %arg, i32 1, i32 2), !dbg !39, !llvm.preserve.access.index !25 + %2 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %1, i64 0), !dbg !40 + call void @llvm.dbg.value(metadata i32 %2, metadata !34, metadata !DIExpression()), !dbg !37 + %3 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %1, i64 1), !dbg !41 + call void @llvm.dbg.value(metadata i32 %3, metadata !35, metadata !DIExpression()), !dbg !37 + %4 = bitcast %struct.s* %arg to i8*, !dbg !42 + %idx.ext = zext i32 %2 to i64, !dbg !43 + %add.ptr = getelementptr i8, i8* %4, i64 %idx.ext, !dbg !43 + call void @bpf_probe_read(i8* nonnull %0, i32 %3, i8* %add.ptr) #5, !dbg !44 + %5 = call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %1, i64 4), !dbg !45 + call void @llvm.dbg.value(metadata i32 %5, metadata !36, metadata !DIExpression()), !dbg !37 + %6 = load i64, i64* %ull, align 8, !dbg !46, !tbaa !47 + call void @llvm.dbg.value(metadata i64 %6, metadata !32, metadata !DIExpression()), !dbg !37 + %sh_prom = zext i32 %5 to i64, !dbg !46 + %shl = shl i64 %6, %sh_prom, !dbg !46 + call void @llvm.dbg.value(metadata i64 %shl, metadata !32, metadata !DIExpression()), !dbg !37 + %7 = call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %1, i64 3), !dbg !51 + %tobool = icmp eq i32 %7, 0, !dbg !51 + %8 = call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %1, i64 5), !dbg !37 + %sh_prom1 = zext i32 %8 to i64, !dbg !37 + %shr = ashr i64 %shl, %sh_prom1, !dbg !53 + %shr3 = lshr i64 %shl, %sh_prom1, !dbg !53 + %retval.0.in = select i1 %tobool, i64 %shr3, i64 %shr, !dbg !53 + %retval.0 = trunc i64 %retval.0.in to i32, !dbg !37 + call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #5, !dbg !54 + ret i32 %retval.0, !dbg !54 +} + +; CHECK: mov64 r{{[0-9]+}}, 4 +; CHECK: mov64 r{{[0-9]+}}, 4 +; CHECK: lsh64 r{{[0-9]+}}, 51 +; CHECK64: arsh64 r{{[0-9]+}}, 60 +; CHECK64: rsh64 r{{[0-9]+}}, 60 +; CHECK32: rsh64 r{{[0-9]+}}, 60 +; CHECK32: arsh64 r{{[0-9]+}}, 60 +; CHECK: mov64 r{{[0-9]+}}, 1 + +; CHECK: .byte 115 # string offset=1 +; CHECK: .ascii ".text" # string offset=30 +; CHECK: .ascii "0:2" # string offset=73 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 30 # Field reloc section string offset=30 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 73 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 73 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 73 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 73 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 73 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 73 +; CHECK-NEXT: .long 3 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 + +; Function Attrs: nounwind readnone +declare i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.ss(%struct.s*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i16(i16*, i64) #2 + +declare dso_local void @bpf_probe_read(i8*, i32, i8*) local_unnamed_addr #3 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #4 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind willreturn } +attributes #2 = { nounwind readnone } +attributes #3 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #4 = { nounwind readnone speculatable willreturn } +attributes #5 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!16, !17, !18} +!llvm.ident = !{!19} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 923aa0ce806f7739b754167239fee2c9a15e2f31)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !12, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 6, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6, !7, !8, !9, !10, !11} +!6 = !DIEnumerator(name: "FIELD_BYTE_OFFSET", value: 0, isUnsigned: true) +!7 = !DIEnumerator(name: "FIELD_BYTE_SIZE", value: 1, isUnsigned: true) +!8 = !DIEnumerator(name: "FIELD_EXISTENCE", value: 2, isUnsigned: true) +!9 = !DIEnumerator(name: "FIELD_SIGNEDNESS", value: 3, isUnsigned: true) +!10 = !DIEnumerator(name: "FIELD_LSHIFT_U64", value: 4, isUnsigned: true) +!11 = !DIEnumerator(name: "FIELD_RSHIFT_U64", value: 5, isUnsigned: true) +!12 = !{!13, !15} +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!14 = !DIDerivedType(tag: DW_TAG_const_type, baseType: null) +!15 = !DIBasicType(name: "long long int", size: 64, encoding: DW_ATE_signed) +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{i32 1, !"wchar_size", i32 4} +!19 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 923aa0ce806f7739b754167239fee2c9a15e2f31)"} +!20 = distinct !DISubprogram(name: "field_read", scope: !1, file: !1, line: 15, type: !21, scopeLine: 15, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !30) +!21 = !DISubroutineType(types: !22) +!22 = !{!23, !24} +!23 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!24 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !25, size: 64) +!25 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 1, size: 64, elements: !26) +!26 = !{!27, !28, !29} +!27 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !25, file: !1, line: 2, baseType: !23, size: 32) +!28 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !25, file: !1, line: 3, baseType: !23, size: 9, offset: 32, flags: DIFlagBitField, extraData: i64 32) +!29 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !25, file: !1, line: 4, baseType: !23, size: 4, offset: 41, flags: DIFlagBitField, extraData: i64 32) +!30 = !{!31, !32, !34, !35, !36} +!31 = !DILocalVariable(name: "arg", arg: 1, scope: !20, file: !1, line: 15, type: !24) +!32 = !DILocalVariable(name: "ull", scope: !20, file: !1, line: 16, type: !33) +!33 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned) +!34 = !DILocalVariable(name: "offset", scope: !20, file: !1, line: 17, type: !4) +!35 = !DILocalVariable(name: "size", scope: !20, file: !1, line: 18, type: !4) +!36 = !DILocalVariable(name: "lshift", scope: !20, file: !1, line: 19, type: !4) +!37 = !DILocation(line: 0, scope: !20) +!38 = !DILocation(line: 16, column: 3, scope: !20) +!39 = !DILocation(line: 17, column: 56, scope: !20) +!40 = !DILocation(line: 17, column: 21, scope: !20) +!41 = !DILocation(line: 18, column: 19, scope: !20) +!42 = !DILocation(line: 21, column: 30, scope: !20) +!43 = !DILocation(line: 21, column: 48, scope: !20) +!44 = !DILocation(line: 21, column: 3, scope: !20) +!45 = !DILocation(line: 22, column: 12, scope: !20) +!46 = !DILocation(line: 26, column: 7, scope: !20) +!47 = !{!48, !48, i64 0} +!48 = !{!"long long", !49, i64 0} +!49 = !{!"omnipotent char", !50, i64 0} +!50 = !{!"Simple C/C++ TBAA"} +!51 = !DILocation(line: 27, column: 7, scope: !52) +!52 = distinct !DILexicalBlock(scope: !20, file: !1, line: 27, column: 7) +!53 = !DILocation(line: 27, column: 7, scope: !20) +!54 = !DILocation(line: 30, column: 1, scope: !20) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-fieldinfo-2.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-fieldinfo-2.ll new file mode 100644 index 00000000000000..5148a2760318d3 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-fieldinfo-2.ll @@ -0,0 +1,263 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK64 %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK32 %s +; Source code: +; struct s { +; int a; +; int b1:9; +; int b2:4; +; }; +; enum { +; FIELD_BYTE_OFFSET = 0, +; FIELD_BYTE_SIZE, +; FIELD_EXISTENCE, +; FIELD_SIGNEDNESS, +; FIELD_LSHIFT_U64, +; FIELD_RSHIFT_U64, +; }; +; int field_read(struct s *arg) { +; unsigned long long ull; +; unsigned offset = __builtin_preserve_field_info(arg->b2, FIELD_BYTE_OFFSET); +; unsigned size = __builtin_preserve_field_info(arg->b2, FIELD_BYTE_SIZE); +; switch(size) { +; case 1: +; ull = *(unsigned char *)((void *)arg + offset); break; +; case 2: +; ull = *(unsigned short *)((void *)arg + offset); break; +; case 4: +; ull = *(unsigned int *)((void *)arg + offset); break; +; case 8: +; ull = *(unsigned long long *)((void *)arg + offset); break; +; } +; ull <<= __builtin_preserve_field_info(arg->b2, FIELD_LSHIFT_U64); +; if (__builtin_preserve_field_info(arg->b2, FIELD_SIGNEDNESS)) +; return ((long long)ull) >>__builtin_preserve_field_info(arg->b2, FIELD_RSHIFT_U64); +; return ull >> __builtin_preserve_field_info(arg->b2, FIELD_RSHIFT_U64); +; } +; Compilation flag: +; clang -target bpfel -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.s = type { i32, i16 } + +; Function Attrs: nounwind readonly +define dso_local i32 @field_read(%struct.s* %arg) local_unnamed_addr #0 !dbg !26 { +entry: + call void @llvm.dbg.value(metadata %struct.s* %arg, metadata !37, metadata !DIExpression()), !dbg !41 + %0 = tail call i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.ss(%struct.s* elementtype(%struct.s) %arg, i32 1, i32 2), !dbg !42, !llvm.preserve.access.index !31 + %1 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %0, i64 0), !dbg !43 + call void @llvm.dbg.value(metadata i32 %1, metadata !39, metadata !DIExpression()), !dbg !41 + %2 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %0, i64 1), !dbg !44 + call void @llvm.dbg.value(metadata i32 %2, metadata !40, metadata !DIExpression()), !dbg !41 + switch i32 %2, label %sw.epilog [ + i32 1, label %sw.bb + i32 2, label %sw.bb1 + i32 4, label %sw.bb5 + i32 8, label %sw.bb9 + ], !dbg !45 + +sw.bb: ; preds = %entry + %3 = bitcast %struct.s* %arg to i8*, !dbg !46 + %idx.ext = zext i32 %1 to i64, !dbg !48 + %add.ptr = getelementptr i8, i8* %3, i64 %idx.ext, !dbg !48 + %4 = load i8, i8* %add.ptr, align 1, !dbg !49, !tbaa !50 + %conv = zext i8 %4 to i64, !dbg !49 + call void @llvm.dbg.value(metadata i64 %conv, metadata !38, metadata !DIExpression()), !dbg !41 + br label %sw.epilog, !dbg !53 + +sw.bb1: ; preds = %entry + %5 = bitcast %struct.s* %arg to i8*, !dbg !54 + %idx.ext2 = zext i32 %1 to i64, !dbg !55 + %add.ptr3 = getelementptr i8, i8* %5, i64 %idx.ext2, !dbg !55 + %6 = bitcast i8* %add.ptr3 to i16*, !dbg !56 + %7 = load i16, i16* %6, align 2, !dbg !57, !tbaa !58 + %conv4 = zext i16 %7 to i64, !dbg !57 + call void @llvm.dbg.value(metadata i64 %conv4, metadata !38, metadata !DIExpression()), !dbg !41 + br label %sw.epilog, !dbg !60 + +sw.bb5: ; preds = %entry + %8 = bitcast %struct.s* %arg to i8*, !dbg !61 + %idx.ext6 = zext i32 %1 to i64, !dbg !62 + %add.ptr7 = getelementptr i8, i8* %8, i64 %idx.ext6, !dbg !62 + %9 = bitcast i8* %add.ptr7 to i32*, !dbg !63 + %10 = load i32, i32* %9, align 4, !dbg !64, !tbaa !65 + %conv8 = zext i32 %10 to i64, !dbg !64 + call void @llvm.dbg.value(metadata i64 %conv8, metadata !38, metadata !DIExpression()), !dbg !41 + br label %sw.epilog, !dbg !67 + +sw.bb9: ; preds = %entry + %11 = bitcast %struct.s* %arg to i8*, !dbg !68 + %idx.ext10 = zext i32 %1 to i64, !dbg !69 + %add.ptr11 = getelementptr i8, i8* %11, i64 %idx.ext10, !dbg !69 + %12 = bitcast i8* %add.ptr11 to i64*, !dbg !70 + %13 = load i64, i64* %12, align 8, !dbg !71, !tbaa !72 + call void @llvm.dbg.value(metadata i64 %13, metadata !38, metadata !DIExpression()), !dbg !41 + br label %sw.epilog, !dbg !74 + +sw.epilog: ; preds = %entry, %sw.bb9, %sw.bb5, %sw.bb1, %sw.bb + %ull.0 = phi i64 [ undef, %entry ], [ %13, %sw.bb9 ], [ %conv8, %sw.bb5 ], [ %conv4, %sw.bb1 ], [ %conv, %sw.bb ] + call void @llvm.dbg.value(metadata i64 %ull.0, metadata !38, metadata !DIExpression()), !dbg !41 + %14 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %0, i64 4), !dbg !75 + %sh_prom = zext i32 %14 to i64, !dbg !76 + %shl = shl i64 %ull.0, %sh_prom, !dbg !76 + call void @llvm.dbg.value(metadata i64 %shl, metadata !38, metadata !DIExpression()), !dbg !41 + %15 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %0, i64 3), !dbg !77 + %tobool = icmp eq i32 %15, 0, !dbg !77 + %16 = tail call i32 @llvm.bpf.preserve.field.info.p0i16(i16* %0, i64 5), !dbg !41 + %sh_prom12 = zext i32 %16 to i64, !dbg !41 + %shr = ashr i64 %shl, %sh_prom12, !dbg !79 + %shr15 = lshr i64 %shl, %sh_prom12, !dbg !79 + %retval.0.in = select i1 %tobool, i64 %shr15, i64 %shr, !dbg !79 + %retval.0 = trunc i64 %retval.0.in to i32, !dbg !41 + ret i32 %retval.0, !dbg !80 +} + +; CHECK: mov64 r{{[0-9]+}}, 4 +; CHECK: mov64 r{{[0-9]+}}, 4 +; CHECK-EL: lsh64 r{{[0-9]+}}, 51 +; CHECK64: rsh64 r{{[0-9]+}}, 60 +; CHECK64: rsh64 r{{[0-9]+}}, 60 +; CHECK32: rsh64 r{{[0-9]+}}, 60 +; CHECK32: arsh64 r{{[0-9]+}}, 60 +; CHECK: mov64 r{{[0-9]+}}, 1 + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 2) +; CHECK: .byte 115 # string offset=1 +; CHECK: .ascii ".text" # string offset=30 +; CHECK: .ascii "0:2" # string offset=36 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 30 # Field reloc section string offset=30 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 3 + +; Function Attrs: nounwind readnone +declare i16* @llvm.preserve.struct.access.index.p0i16.p0s_struct.ss(%struct.s*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @llvm.bpf.preserve.field.info.p0i16(i16*, i64) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!22, !23, !24} +!llvm.ident = !{!25} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 923aa0ce806f7739b754167239fee2c9a15e2f31)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !12, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !1, line: 6, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6, !7, !8, !9, !10, !11} +!6 = !DIEnumerator(name: "FIELD_BYTE_OFFSET", value: 0, isUnsigned: true) +!7 = !DIEnumerator(name: "FIELD_BYTE_SIZE", value: 1, isUnsigned: true) +!8 = !DIEnumerator(name: "FIELD_EXISTENCE", value: 2, isUnsigned: true) +!9 = !DIEnumerator(name: "FIELD_SIGNEDNESS", value: 3, isUnsigned: true) +!10 = !DIEnumerator(name: "FIELD_LSHIFT_U64", value: 4, isUnsigned: true) +!11 = !DIEnumerator(name: "FIELD_RSHIFT_U64", value: 5, isUnsigned: true) +!12 = !{!13, !15, !16, !18, !19, !21} +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!14 = !DIBasicType(name: "unsigned char", size: 8, encoding: DW_ATE_unsigned_char) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64) +!17 = !DIBasicType(name: "unsigned short", size: 16, encoding: DW_ATE_unsigned) +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64) +!20 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned) +!21 = !DIBasicType(name: "long long int", size: 64, encoding: DW_ATE_signed) +!22 = !{i32 2, !"Dwarf Version", i32 4} +!23 = !{i32 2, !"Debug Info Version", i32 3} +!24 = !{i32 1, !"wchar_size", i32 4} +!25 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 923aa0ce806f7739b754167239fee2c9a15e2f31)"} +!26 = distinct !DISubprogram(name: "field_read", scope: !1, file: !1, line: 14, type: !27, scopeLine: 14, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !36) +!27 = !DISubroutineType(types: !28) +!28 = !{!29, !30} +!29 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!30 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !31, size: 64) +!31 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 1, size: 64, elements: !32) +!32 = !{!33, !34, !35} +!33 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !31, file: !1, line: 2, baseType: !29, size: 32) +!34 = !DIDerivedType(tag: DW_TAG_member, name: "b1", scope: !31, file: !1, line: 3, baseType: !29, size: 9, offset: 32, flags: DIFlagBitField, extraData: i64 32) +!35 = !DIDerivedType(tag: DW_TAG_member, name: "b2", scope: !31, file: !1, line: 4, baseType: !29, size: 4, offset: 41, flags: DIFlagBitField, extraData: i64 32) +!36 = !{!37, !38, !39, !40} +!37 = !DILocalVariable(name: "arg", arg: 1, scope: !26, file: !1, line: 14, type: !30) +!38 = !DILocalVariable(name: "ull", scope: !26, file: !1, line: 15, type: !20) +!39 = !DILocalVariable(name: "offset", scope: !26, file: !1, line: 16, type: !4) +!40 = !DILocalVariable(name: "size", scope: !26, file: !1, line: 17, type: !4) +!41 = !DILocation(line: 0, scope: !26) +!42 = !DILocation(line: 16, column: 56, scope: !26) +!43 = !DILocation(line: 16, column: 21, scope: !26) +!44 = !DILocation(line: 17, column: 19, scope: !26) +!45 = !DILocation(line: 18, column: 3, scope: !26) +!46 = !DILocation(line: 20, column: 30, scope: !47) +!47 = distinct !DILexicalBlock(scope: !26, file: !1, line: 18, column: 16) +!48 = !DILocation(line: 20, column: 42, scope: !47) +!49 = !DILocation(line: 20, column: 11, scope: !47) +!50 = !{!51, !51, i64 0} +!51 = !{!"omnipotent char", !52, i64 0} +!52 = !{!"Simple C/C++ TBAA"} +!53 = !DILocation(line: 20, column: 53, scope: !47) +!54 = !DILocation(line: 22, column: 31, scope: !47) +!55 = !DILocation(line: 22, column: 43, scope: !47) +!56 = !DILocation(line: 22, column: 12, scope: !47) +!57 = !DILocation(line: 22, column: 11, scope: !47) +!58 = !{!59, !59, i64 0} +!59 = !{!"short", !51, i64 0} +!60 = !DILocation(line: 22, column: 54, scope: !47) +!61 = !DILocation(line: 24, column: 29, scope: !47) +!62 = !DILocation(line: 24, column: 41, scope: !47) +!63 = !DILocation(line: 24, column: 12, scope: !47) +!64 = !DILocation(line: 24, column: 11, scope: !47) +!65 = !{!66, !66, i64 0} +!66 = !{!"int", !51, i64 0} +!67 = !DILocation(line: 24, column: 52, scope: !47) +!68 = !DILocation(line: 26, column: 35, scope: !47) +!69 = !DILocation(line: 26, column: 47, scope: !47) +!70 = !DILocation(line: 26, column: 12, scope: !47) +!71 = !DILocation(line: 26, column: 11, scope: !47) +!72 = !{!73, !73, i64 0} +!73 = !{!"long long", !51, i64 0} +!74 = !DILocation(line: 26, column: 58, scope: !47) +!75 = !DILocation(line: 28, column: 11, scope: !26) +!76 = !DILocation(line: 28, column: 7, scope: !26) +!77 = !DILocation(line: 29, column: 7, scope: !78) +!78 = distinct !DILexicalBlock(scope: !26, file: !1, line: 29, column: 7) +!79 = !DILocation(line: 29, column: 7, scope: !26) +!80 = !DILocation(line: 32, column: 1, scope: !26) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-global-1.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-global-1.ll new file mode 100644 index 00000000000000..1b61455100697f --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-global-1.ll @@ -0,0 +1,83 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; typedef struct v3 { int a; int b; } __v3; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const int *arg); +; __v3 g __attribute__((section("stats"))); +; int test() { +; return get_value(_(&g.b)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i32, i32 } + +@g = dso_local global %struct.v3 zeroinitializer, section "stats", align 4, !dbg !0 + +; Function Attrs: nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !16 { +entry: + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) nonnull @g, i32 1, i32 1), !dbg !19, !llvm.preserve.access.index !7 + %call = tail call i32 @get_value(i32* %0) #3, !dbg !20 + ret i32 %call, !dbg !21 +} + +; CHECK: mov64 r2, 4 +; CHECK: lddw r1, g +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 16 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "v3" # string offset=16 +; CHECK: .ascii "0:1" # string offset=23 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!12, !13, !14} +!llvm.ident = !{!15} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 4, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !3, line: 1, baseType: !7) +!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !3, line: 1, size: 64, elements: !8) +!8 = !{!9, !11} +!9 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !7, file: !3, line: 1, baseType: !10, size: 32) +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !7, file: !3, line: 1, baseType: !10, size: 32, offset: 32) +!12 = !{i32 2, !"Dwarf Version", i32 4} +!13 = !{i32 2, !"Debug Info Version", i32 3} +!14 = !{i32 1, !"wchar_size", i32 4} +!15 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!16 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 5, type: !17, scopeLine: 5, isDefinition: true, isOptimized: true, unit: !2, retainedNodes: !4) +!17 = !DISubroutineType(types: !18) +!18 = !{!10} +!19 = !DILocation(line: 6, column: 20, scope: !16) +!20 = !DILocation(line: 6, column: 10, scope: !16) +!21 = !DILocation(line: 6, column: 3, scope: !16) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-global-2.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-global-2.ll new file mode 100644 index 00000000000000..e094c55d67ca59 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-global-2.ll @@ -0,0 +1,99 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; typedef struct v3 { int a; int b; } __v3; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const int *arg); +; __v3 g[4][5] __attribute__((section("stats"))); +; int test() { +; return get_value(_(&g[1][2].b)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i32, i32 } + +@g = dso_local global [4 x [5 x %struct.v3]] zeroinitializer, section "stats", align 4, !dbg !0 + +; Function Attrs: nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !23 { +entry: + %0 = tail call [5 x %struct.v3]* @llvm.preserve.array.access.index.p0a5s_struct.v3s.p0a4a5s_struct.v3s([4 x [5 x %struct.v3]]* elementtype([4 x [5 x %struct.v3]]) nonnull @g, i32 1, i32 1), !dbg !26, !llvm.preserve.access.index !6 + %1 = tail call %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0a5s_struct.v3s([5 x %struct.v3]* elementtype([5 x %struct.v3]) %0, i32 1, i32 2), !dbg !26, !llvm.preserve.access.index !16 + %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %1, i32 1, i32 1), !dbg !26, !llvm.preserve.access.index !8 + %call = tail call i32 @get_value(i32* %2) #3, !dbg !27 + ret i32 %call, !dbg !28 +} + +; CHECK: mov64 r2, 60 +; CHECK: lddw r1, g +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 16 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "v3" # string offset=16 +; CHECK: .ascii "7:1" # string offset=23 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 0 + + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare [5 x %struct.v3]* @llvm.preserve.array.access.index.p0a5s_struct.v3s.p0a4a5s_struct.v3s([4 x [5 x %struct.v3]]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0a5s_struct.v3s([5 x %struct.v3]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!19, !20, !21} +!llvm.ident = !{!22} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 4, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !18, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!4 = !{} +!5 = !{!6, !16} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 1280, elements: !13) +!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !3, line: 1, baseType: !8) +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !3, line: 1, size: 64, elements: !9) +!9 = !{!10, !12} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !3, line: 1, baseType: !11, size: 32) +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !3, line: 1, baseType: !11, size: 32, offset: 32) +!13 = !{!14, !15} +!14 = !DISubrange(count: 4) +!15 = !DISubrange(count: 5) +!16 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 320, elements: !17) +!17 = !{!15} +!18 = !{!0} +!19 = !{i32 2, !"Dwarf Version", i32 4} +!20 = !{i32 2, !"Debug Info Version", i32 3} +!21 = !{i32 1, !"wchar_size", i32 4} +!22 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!23 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 5, type: !24, scopeLine: 5, isDefinition: true, isOptimized: true, unit: !2, retainedNodes: !4) +!24 = !DISubroutineType(types: !25) +!25 = !{!11} +!26 = !DILocation(line: 6, column: 20, scope: !23) +!27 = !DILocation(line: 6, column: 10, scope: !23) +!28 = !DILocation(line: 6, column: 3, scope: !23) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-global-3.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-global-3.ll new file mode 100644 index 00000000000000..d7845097d6ee51 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-global-3.ll @@ -0,0 +1,88 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; typedef struct v3 { int a; int b; } __v3; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const int *arg); +; __v3 *g __attribute__((section("stats"))); +; int test() { +; return get_value(_(&g->b)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i32, i32 } + +@g = dso_local local_unnamed_addr global %struct.v3* null, section "stats", align 8, !dbg !0 + +; Function Attrs: nounwind +define dso_local i32 @test() local_unnamed_addr #0 !dbg !17 { +entry: + %0 = load %struct.v3*, %struct.v3** @g, align 8, !dbg !20, !tbaa !21 + %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %0, i32 1, i32 1), !dbg !20, !llvm.preserve.access.index !8 + %call = tail call i32 @get_value(i32* %1) #3, !dbg !25 + ret i32 %call, !dbg !26 +} + +; CHECK: mov64 r2, 4 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 16 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) + +; CHECK: .ascii ".text" # string offset=10 +; CHECK: .ascii "v3" # string offset=16 +; CHECK: .ascii "0:1" # string offset=23 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 10 # Field reloc section string offset=10 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!13, !14, !15} +!llvm.ident = !{!16} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 4, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !3, line: 1, baseType: !8) +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !3, line: 1, size: 64, elements: !9) +!9 = !{!10, !12} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !3, line: 1, baseType: !11, size: 32) +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !3, line: 1, baseType: !11, size: 32, offset: 32) +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{i32 1, !"wchar_size", i32 4} +!16 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!17 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 5, type: !18, scopeLine: 5, isDefinition: true, isOptimized: true, unit: !2, retainedNodes: !4) +!18 = !DISubroutineType(types: !19) +!19 = !{!11} +!20 = !DILocation(line: 6, column: 20, scope: !17) +!21 = !{!22, !22, i64 0} +!22 = !{!"any pointer", !23, i64 0} +!23 = !{!"omnipotent char", !24, i64 0} +!24 = !{!"Simple C/C++ TBAA"} +!25 = !DILocation(line: 6, column: 10, scope: !17) +!26 = !DILocation(line: 6, column: 3, scope: !17) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-ignore.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-ignore.ll new file mode 100644 index 00000000000000..4734c03964ab75 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-ignore.ll @@ -0,0 +1,65 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const int *arg); +; int test(int *arg) { +; return get_value(_(&arg[4])); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +; Function Attrs: nounwind +define dso_local i32 @test(i32* %arg) local_unnamed_addr #0 !dbg !10 { +entry: + call void @llvm.dbg.value(metadata i32* %arg, metadata !14, metadata !DIExpression()), !dbg !15 + %0 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32* elementtype(i32) %arg, i32 0, i32 4), !dbg !16, !llvm.preserve.access.index !4 + %call = tail call i32 @get_value(i32* %0) #4, !dbg !17 + ret i32 %call, !dbg !18 +} + +; CHECK: add64 r1, 16 +; CHECK: call get_value +; CHECK: .section .BTF.ext,"",@progbits +; CHECK-NOT: .long 16 # FieldReloc + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32*, i32, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !{i32 2, !"Dwarf Version", i32 4} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!10 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !11, scopeLine: 3, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !13) +!11 = !DISubroutineType(types: !12) +!12 = !{!5, !4} +!13 = !{!14} +!14 = !DILocalVariable(name: "arg", arg: 1, scope: !10, file: !1, line: 3, type: !4) +!15 = !DILocation(line: 0, scope: !10) +!16 = !DILocation(line: 4, column: 20, scope: !10) +!17 = !DILocation(line: 4, column: 10, scope: !10) +!18 = !DILocation(line: 4, column: 3, scope: !10) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-middle-chain.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-middle-chain.ll new file mode 100644 index 00000000000000..cdd13eccffd783 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-middle-chain.ll @@ -0,0 +1,133 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct t1 { +; int c; +; }; +; struct s1 { +; struct t1 b; +; }; +; struct r1 { +; struct s1 a; +; }; +; #define _(x) __builtin_preserve_access_index(x) +; void test1(void *p1, void *p2, void *p3); +; void test(struct r1 *arg) { +; struct s1 *ps = _(&arg->a); +; struct t1 *pt = _(&arg->a.b); +; int *pi = _(&arg->a.b.c); +; test1(ps, pt, pi); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.r1 = type { %struct.s1 } +%struct.s1 = type { %struct.t1 } +%struct.t1 = type { i32 } + +; Function Attrs: nounwind +define dso_local void @test(%struct.r1* %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.r1* %arg, metadata !22, metadata !DIExpression()), !dbg !29 + %0 = tail call %struct.s1* @llvm.preserve.struct.access.index.p0s_struct.s1s.p0s_struct.r1s(%struct.r1* elementtype(%struct.r1) %arg, i32 0, i32 0), !dbg !30, !llvm.preserve.access.index !11 + call void @llvm.dbg.value(metadata %struct.s1* %0, metadata !23, metadata !DIExpression()), !dbg !29 + %1 = tail call %struct.t1* @llvm.preserve.struct.access.index.p0s_struct.t1s.p0s_struct.s1s(%struct.s1* elementtype(%struct.s1) %0, i32 0, i32 0), !dbg !31, !llvm.preserve.access.index !14 + call void @llvm.dbg.value(metadata %struct.t1* %1, metadata !25, metadata !DIExpression()), !dbg !29 + %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.t1s(%struct.t1* elementtype(%struct.t1) %1, i32 0, i32 0), !dbg !32, !llvm.preserve.access.index !17 + call void @llvm.dbg.value(metadata i32* %2, metadata !27, metadata !DIExpression()), !dbg !29 + %3 = bitcast %struct.s1* %0 to i8*, !dbg !33 + %4 = bitcast %struct.t1* %1 to i8*, !dbg !34 + %5 = bitcast i32* %2 to i8*, !dbg !35 + tail call void @test1(i8* %3, i8* %4, i8* %5) #4, !dbg !36 + ret void, !dbg !37 +} + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 2) + +; CHECK: .ascii "r1" # string offset=1 +; CHECK: .ascii ".text" # string offset=29 +; CHECK: .ascii "0:0" # string offset=72 +; CHECK: .ascii "0:0:0" # string offset=76 +; CHECK: .ascii "0:0:0:0" # string offset=82 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 29 # Field reloc section string offset=29 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 76 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 82 +; CHECK-NEXT: .long 0 + +; Function Attrs: nounwind readnone +declare %struct.s1* @llvm.preserve.struct.access.index.p0s_struct.s1s.p0s_struct.r1s(%struct.r1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare %struct.t1* @llvm.preserve.struct.access.index.p0s_struct.t1s.p0s_struct.s1s(%struct.s1*, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.t1s(%struct.t1*, i32, i32) #1 + +declare dso_local void @test1(i8*, i8*, i8*) local_unnamed_addr #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 42b3328a2368b38fba6bdb0c616fe6c5520e3bc5)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git 42b3328a2368b38fba6bdb0c616fe6c5520e3bc5)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 12, type: !8, scopeLine: 12, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !21) +!8 = !DISubroutineType(types: !9) +!9 = !{null, !10} +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64) +!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "r1", file: !1, line: 7, size: 32, elements: !12) +!12 = !{!13} +!13 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !11, file: !1, line: 8, baseType: !14, size: 32) +!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1", file: !1, line: 4, size: 32, elements: !15) +!15 = !{!16} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !14, file: !1, line: 5, baseType: !17, size: 32) +!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !1, line: 1, size: 32, elements: !18) +!18 = !{!19} +!19 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !17, file: !1, line: 2, baseType: !20, size: 32) +!20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!21 = !{!22, !23, !25, !27} +!22 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 12, type: !10) +!23 = !DILocalVariable(name: "ps", scope: !7, file: !1, line: 13, type: !24) +!24 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!25 = !DILocalVariable(name: "pt", scope: !7, file: !1, line: 14, type: !26) +!26 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64) +!27 = !DILocalVariable(name: "pi", scope: !7, file: !1, line: 15, type: !28) +!28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64) +!29 = !DILocation(line: 0, scope: !7) +!30 = !DILocation(line: 13, column: 19, scope: !7) +!31 = !DILocation(line: 14, column: 19, scope: !7) +!32 = !DILocation(line: 15, column: 13, scope: !7) +!33 = !DILocation(line: 16, column: 9, scope: !7) +!34 = !DILocation(line: 16, column: 13, scope: !7) +!35 = !DILocation(line: 16, column: 17, scope: !7) +!36 = !DILocation(line: 16, column: 3, scope: !7) +!37 = !DILocation(line: 17, column: 1, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-multi-array-1.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-multi-array-1.ll new file mode 100644 index 00000000000000..15519038dfbdbd --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-multi-array-1.ll @@ -0,0 +1,105 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; typedef int __int; +; typedef struct v3 { int a; __int b[4][4]; } __v3; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const int *arg); +; int test(__v3 *arg) { +; return get_value(_(&arg[1].b[2][3])); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i32, [4 x [4 x i32]] } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !21 { +entry: + call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !25, metadata !DIExpression()), !dbg !26 + %0 = tail call %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %arg, i32 0, i32 1), !dbg !27, !llvm.preserve.access.index !4 + %1 = tail call [4 x [4 x i32]]* @llvm.preserve.struct.access.index.p0a4a4i32.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %0, i32 1, i32 1), !dbg !27, !llvm.preserve.access.index !6 + %2 = tail call [4 x i32]* @llvm.preserve.array.access.index.p0a4i32.p0a4a4i32([4 x [4 x i32]]* elementtype([4 x [4 x i32]]) %1, i32 1, i32 2), !dbg !27, !llvm.preserve.access.index !11 + %3 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]* elementtype([4 x i32]) %2, i32 1, i32 3), !dbg !27, !llvm.preserve.access.index !15 + %call = tail call i32 @get_value(i32* %3) #4, !dbg !28 + ret i32 %call, !dbg !29 +} + +; CHECK: mov64 r2, 116 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) + +; CHECK: .ascii "v3" # string offset=6 +; CHECK: .ascii ".text" # string offset=52 +; CHECK: .ascii "1:1:2:3" # string offset=58 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 52 # Field reloc section string offset=52 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 58 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare [4 x [4 x i32]]* @llvm.preserve.struct.access.index.p0a4a4i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare [4 x i32]* @llvm.preserve.array.access.index.p0a4i32.p0a4a4i32([4 x [4 x i32]]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]*, i32, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!17, !18, !19} +!llvm.ident = !{!20} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4, !11, !15} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 2, baseType: !6) +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 2, size: 544, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 2, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 2, baseType: !11, size: 512, offset: 32) +!11 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 512, elements: !13) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 1, baseType: !9) +!13 = !{!14, !14} +!14 = !DISubrange(count: 4) +!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 128, elements: !16) +!16 = !{!14} +!17 = !{i32 2, !"Dwarf Version", i32 4} +!18 = !{i32 2, !"Debug Info Version", i32 3} +!19 = !{i32 1, !"wchar_size", i32 4} +!20 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!21 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 5, type: !22, scopeLine: 5, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !24) +!22 = !DISubroutineType(types: !23) +!23 = !{!9, !4} +!24 = !{!25} +!25 = !DILocalVariable(name: "arg", arg: 1, scope: !21, file: !1, line: 5, type: !4) +!26 = !DILocation(line: 0, scope: !21) +!27 = !DILocation(line: 6, column: 20, scope: !21) +!28 = !DILocation(line: 6, column: 10, scope: !21) +!29 = !DILocation(line: 6, column: 3, scope: !21) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-multi-array-2.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-multi-array-2.ll new file mode 100644 index 00000000000000..d2613698f1e3f7 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-multi-array-2.ll @@ -0,0 +1,111 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; typedef int __int; +; typedef struct v3 { int a; __int b[4][4][4]; } __v3; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const int *arg); +; int test(__v3 *arg) { +; return get_value(_(&arg[1].b[2][3][2])); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i32, [4 x [4 x [4 x i32]]] } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !23 { +entry: + call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !27, metadata !DIExpression()), !dbg !28 + %0 = tail call %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %arg, i32 0, i32 1), !dbg !29, !llvm.preserve.access.index !4 + %1 = tail call [4 x [4 x [4 x i32]]]* @llvm.preserve.struct.access.index.p0a4a4a4i32.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %0, i32 1, i32 1), !dbg !29, !llvm.preserve.access.index !6 + %2 = tail call [4 x [4 x i32]]* @llvm.preserve.array.access.index.p0a4a4i32.p0a4a4a4i32([4 x [4 x [4 x i32]]]* elementtype([4 x [4 x [4 x i32]]]) %1, i32 1, i32 2), !dbg !29, !llvm.preserve.access.index !11 + %3 = tail call [4 x i32]* @llvm.preserve.array.access.index.p0a4i32.p0a4a4i32([4 x [4 x i32]]* elementtype([4 x [4 x i32]]) %2, i32 1, i32 3), !dbg !29, !llvm.preserve.access.index !15 + %4 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]* elementtype([4 x i32]) %3, i32 1, i32 2), !dbg !29, !llvm.preserve.access.index !17 + %call = tail call i32 @get_value(i32* %4) #4, !dbg !30 + ret i32 %call, !dbg !31 +} + +; CHECK: mov64 r2, 448 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) + +; CHECK: .ascii "v3" # string offset=6 +; CHECK: .ascii ".text" # string offset=52 +; CHECK: .ascii "1:1:2:3:2" # string offset=58 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 52 # Field reloc section string offset=52 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 58 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare [4 x [4 x [4 x i32]]]* @llvm.preserve.struct.access.index.p0a4a4a4i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare [4 x [4 x i32]]* @llvm.preserve.array.access.index.p0a4a4i32.p0a4a4a4i32([4 x [4 x [4 x i32]]]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare [4 x i32]* @llvm.preserve.array.access.index.p0a4i32.p0a4a4i32([4 x [4 x i32]]*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]*, i32, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!19, !20, !21} +!llvm.ident = !{!22} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4, !11, !15, !17} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 2, baseType: !6) +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 2, size: 2080, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 2, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 2, baseType: !11, size: 2048, offset: 32) +!11 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 2048, elements: !13) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 1, baseType: !9) +!13 = !{!14, !14, !14} +!14 = !DISubrange(count: 4) +!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 512, elements: !16) +!16 = !{!14, !14} +!17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 128, elements: !18) +!18 = !{!14} +!19 = !{i32 2, !"Dwarf Version", i32 4} +!20 = !{i32 2, !"Debug Info Version", i32 3} +!21 = !{i32 1, !"wchar_size", i32 4} +!22 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!23 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 5, type: !24, scopeLine: 5, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !26) +!24 = !DISubroutineType(types: !25) +!25 = !{!9, !4} +!26 = !{!27} +!27 = !DILocalVariable(name: "arg", arg: 1, scope: !23, file: !1, line: 5, type: !4) +!28 = !DILocation(line: 0, scope: !23) +!29 = !DILocation(line: 6, column: 20, scope: !23) +!30 = !DILocation(line: 6, column: 10, scope: !23) +!31 = !DILocation(line: 6, column: 3, scope: !23) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-multilevel.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-multilevel.ll new file mode 100644 index 00000000000000..76cec1b359744c --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-multilevel.ll @@ -0,0 +1,199 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct net_device { +; int dev_id; +; int others; +; }; +; struct sk_buff { +; int i; +; struct net_device dev; +; }; +; #define _(x) (__builtin_preserve_access_index(x)) +; static int (*bpf_probe_read)(void *dst, int size, void *unsafe_ptr) +; = (void *) 4; +; +; int bpf_prog(struct sk_buff *ctx) { +; int dev_id; +; bpf_probe_read(&dev_id, sizeof(int), _(&ctx->dev.dev_id)); +; return dev_id; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.sk_buff = type { i32, %struct.net_device } +%struct.net_device = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @bpf_prog(%struct.sk_buff*) local_unnamed_addr #0 !dbg !15 { + %2 = alloca i32, align 4 + call void @llvm.dbg.value(metadata %struct.sk_buff* %0, metadata !28, metadata !DIExpression()), !dbg !30 + %3 = bitcast i32* %2 to i8*, !dbg !31 + call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %3) #4, !dbg !31 + %4 = tail call %struct.net_device* @llvm.preserve.struct.access.index.p0s_struct.net_devices.p0s_struct.sk_buffs(%struct.sk_buff* elementtype(%struct.sk_buff) %0, i32 1, i32 1), !dbg !32, !llvm.preserve.access.index !19 + %5 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.net_devices(%struct.net_device* elementtype(%struct.net_device) %4, i32 0, i32 0), !dbg !32, !llvm.preserve.access.index !23 + %6 = bitcast i32* %5 to i8*, !dbg !32 + %7 = call i32 inttoptr (i64 4 to i32 (i8*, i32, i8*)*)(i8* nonnull %3, i32 4, i8* %6) #4, !dbg !33 + %8 = load i32, i32* %2, align 4, !dbg !34, !tbaa !35 + call void @llvm.dbg.value(metadata i32 %8, metadata !29, metadata !DIExpression()), !dbg !30 + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %3) #4, !dbg !39 + ret i32 %8, !dbg !40 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 132 +; CHECK-NEXT: .long 132 +; CHECK-NEXT: .long 106 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 2) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 15 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 19 # BTF_KIND_STRUCT(id = 4) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 30 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 37 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 5) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 44 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 48 # BTF_KIND_FUNC(id = 6) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "sk_buff" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 105 # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "dev" # string offset=11 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=15 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "net_device" # string offset=19 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "dev_id" # string offset=30 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "others" # string offset=37 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "ctx" # string offset=44 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "bpf_prog" # string offset=48 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=57 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/llvm/test.c" # string offset=63 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "0:1:0" # string offset=100 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long {{[0-9]+}} +; CHECK-NEXT: .long {{[0-9]+}} +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 8 # FuncInfo + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 57 # Field reloc section string offset=57 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 100 +; CHECK-NEXT: .long 0 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone +declare %struct.net_device* @llvm.preserve.struct.access.index.p0s_struct.net_devices.p0s_struct.sk_buffs(%struct.sk_buff*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.net_devices(%struct.net_device*, i32 immarg, i32 immarg) #2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 (trunk 360739) (llvm/trunk 360747)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm") +!2 = !{} +!3 = !{!4} +!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression()) +!5 = distinct !DIGlobalVariable(name: "bpf_probe_read", scope: !0, file: !1, line: 10, type: !6, isLocal: true, isDefinition: true) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !10, !9, !10} +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 9.0.0 (trunk 360739) (llvm/trunk 360747)"} +!15 = distinct !DISubprogram(name: "bpf_prog", scope: !1, file: !1, line: 13, type: !16, scopeLine: 13, flags: DIFlagPrototyped, isLocal: false, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !27) +!16 = !DISubroutineType(types: !17) +!17 = !{!9, !18} +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !1, line: 5, size: 96, elements: !20) +!20 = !{!21, !22} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !19, file: !1, line: 6, baseType: !9, size: 32) +!22 = !DIDerivedType(tag: DW_TAG_member, name: "dev", scope: !19, file: !1, line: 7, baseType: !23, size: 64, offset: 32) +!23 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "net_device", file: !1, line: 1, size: 64, elements: !24) +!24 = !{!25, !26} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "dev_id", scope: !23, file: !1, line: 2, baseType: !9, size: 32) +!26 = !DIDerivedType(tag: DW_TAG_member, name: "others", scope: !23, file: !1, line: 3, baseType: !9, size: 32, offset: 32) +!27 = !{!28, !29} +!28 = !DILocalVariable(name: "ctx", arg: 1, scope: !15, file: !1, line: 13, type: !18) +!29 = !DILocalVariable(name: "dev_id", scope: !15, file: !1, line: 14, type: !9) +!30 = !DILocation(line: 0, scope: !15) +!31 = !DILocation(line: 14, column: 3, scope: !15) +!32 = !DILocation(line: 15, column: 40, scope: !15) +!33 = !DILocation(line: 15, column: 3, scope: !15) +!34 = !DILocation(line: 16, column: 10, scope: !15) +!35 = !{!36, !36, i64 0} +!36 = !{!"int", !37, i64 0} +!37 = !{!"omnipotent char", !38, i64 0} +!38 = !{!"Simple C/C++ TBAA"} +!39 = !DILocation(line: 17, column: 1, scope: !15) +!40 = !DILocation(line: 16, column: 3, scope: !15) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-pointer-1.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-pointer-1.ll new file mode 100644 index 00000000000000..0ce6ed8b1912ec --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-pointer-1.ll @@ -0,0 +1,87 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; typedef struct v3 { int a; int b; } __v3; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const int *arg); +; int test(__v3 *arg) { +; return get_value(_(&arg[1])); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !15 { +entry: + call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !19, metadata !DIExpression()), !dbg !20 + %0 = tail call %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %arg, i32 0, i32 1), !dbg !21, !llvm.preserve.access.index !4 + %1 = getelementptr inbounds %struct.v3, %struct.v3* %0, i64 0, i32 0, !dbg !21 + %call = tail call i32 @get_value(i32* %1) #4, !dbg !22 + ret i32 %call, !dbg !23 +} + +; CHECK: mov64 r2, 8 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) + +; CHECK: .ascii "v3" # string offset=6 +; CHECK: .ascii ".text" # string offset=26 +; CHECK: .byte 49 # string offset=32 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 26 # Field reloc section string offset=26 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 1, baseType: !6) +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 1, size: 64, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32, offset: 32) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!15 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !16, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!9, !4} +!18 = !{!19} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 4, type: !4) +!20 = !DILocation(line: 0, scope: !15) +!21 = !DILocation(line: 5, column: 20, scope: !15) +!22 = !DILocation(line: 5, column: 10, scope: !15) +!23 = !DILocation(line: 5, column: 3, scope: !15) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-pointer-2.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-pointer-2.ll new file mode 100644 index 00000000000000..c401fe8d311e04 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-pointer-2.ll @@ -0,0 +1,89 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; typedef struct v3 { int a; int b; } __v3; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const int *arg); +; int test(__v3 *arg) { +; return get_value(_(&arg[1].b)); +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.v3 = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !15 { +entry: + call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !19, metadata !DIExpression()), !dbg !20 + %0 = tail call %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %arg, i32 0, i32 1), !dbg !21, !llvm.preserve.access.index !4 + %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3* elementtype(%struct.v3) %0, i32 1, i32 1), !dbg !21, !llvm.preserve.access.index !6 + %call = tail call i32 @get_value(i32* %1) #4, !dbg !22 + ret i32 %call, !dbg !23 +} + +; CHECK: mov64 r2, 12 +; CHECK-NEXT: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) +; CHECK: .ascii "v3" # string offset=6 +; CHECK: .ascii ".text" # string offset=26 +; CHECK: .ascii "1:1" # string offset=32 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 26 # Field reloc section string offset=26 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long [[TID1]] +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable willreturn } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 1, baseType: !6) +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 1, size: 64, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32, offset: 32) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} +!15 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !16, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!9, !4} +!18 = !{!19} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 4, type: !4) +!20 = !DILocation(line: 0, scope: !15) +!21 = !DILocation(line: 5, column: 20, scope: !15) +!22 = !DILocation(line: 5, column: 10, scope: !15) +!23 = !DILocation(line: 5, column: 3, scope: !15) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-struct-anonymous.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-struct-anonymous.ll new file mode 100644 index 00000000000000..d0381945891618 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-struct-anonymous.ll @@ -0,0 +1,215 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct sk_buff { +; int i; +; struct { +; int dev_id; +; int others; +; } dev[10]; +; }; +; #define _(x) (__builtin_preserve_access_index(x)) +; static int (*bpf_probe_read)(void *dst, int size, void *unsafe_ptr) +; = (void *) 4; +; +; int bpf_prog(struct sk_buff *ctx) { +; int dev_id; +; bpf_probe_read(&dev_id, sizeof(int), _(&ctx->dev[5].dev_id)); +; return dev_id; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.sk_buff = type { i32, [10 x %struct.anon] } +%struct.anon = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @bpf_prog(%struct.sk_buff*) local_unnamed_addr #0 !dbg !15 { + %2 = alloca i32, align 4 + call void @llvm.dbg.value(metadata %struct.sk_buff* %0, metadata !31, metadata !DIExpression()), !dbg !33 + %3 = bitcast i32* %2 to i8*, !dbg !34 + call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %3) #4, !dbg !34 + %4 = tail call [10 x %struct.anon]* @llvm.preserve.struct.access.index.p0a10s_struct.anons.p0s_struct.sk_buffs(%struct.sk_buff* elementtype(%struct.sk_buff) %0, i32 1, i32 1), !dbg !35, !llvm.preserve.access.index !19 + %5 = tail call %struct.anon* @llvm.preserve.array.access.index.p0s_struct.anons.p0a10s_struct.anons([10 x %struct.anon]* elementtype([10 x %struct.anon]) %4, i32 1, i32 5), !dbg !35, !llvm.preserve.access.index !23 + %6 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.anons(%struct.anon* elementtype(%struct.anon) %5, i32 0, i32 0), !dbg !35, !llvm.preserve.access.index !24 + %7 = bitcast i32* %6 to i8*, !dbg !35 + %8 = call i32 inttoptr (i64 4 to i32 (i8*, i32, i8*)*)(i8* nonnull %3, i32 4, i8* %7) #4, !dbg !36 + %9 = load i32, i32* %2, align 4, !dbg !37, !tbaa !38 + call void @llvm.dbg.value(metadata i32 %9, metadata !32, metadata !DIExpression()), !dbg !33 + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %3) #4, !dbg !42 + ret i32 %9, !dbg !43 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 172 +; CHECK-NEXT: .long 172 +; CHECK-NEXT: .long 117 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 2) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 84 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 15 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 4) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 19 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 5) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 33 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 7) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 53 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 57 # BTF_KIND_FUNC(id = 8) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "sk_buff" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 105 # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "dev" # string offset=11 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=15 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "dev_id" # string offset=19 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "others" # string offset=26 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=33 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "ctx" # string offset=53 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "bpf_prog" # string offset=57 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=66 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/llvm/test.c" # string offset=72 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "0:1:5:0" # string offset=109 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long {{[0-9]+}} +; CHECK-NEXT: .long {{[0-9]+}} +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 8 # FuncInfo + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 66 # Field reloc section string offset=66 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 109 +; CHECK-NEXT: .long 0 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone +declare [10 x %struct.anon]* @llvm.preserve.struct.access.index.p0a10s_struct.anons.p0s_struct.sk_buffs(%struct.sk_buff*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare %struct.anon* @llvm.preserve.array.access.index.p0s_struct.anons.p0a10s_struct.anons([10 x %struct.anon]*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.anons(%struct.anon*, i32 immarg, i32 immarg) #2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 (trunk 360739) (llvm/trunk 360747)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm") +!2 = !{} +!3 = !{!4} +!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression()) +!5 = distinct !DIGlobalVariable(name: "bpf_probe_read", scope: !0, file: !1, line: 9, type: !6, isLocal: true, isDefinition: true) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !10, !9, !10} +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 9.0.0 (trunk 360739) (llvm/trunk 360747)"} +!15 = distinct !DISubprogram(name: "bpf_prog", scope: !1, file: !1, line: 12, type: !16, scopeLine: 12, flags: DIFlagPrototyped, isLocal: false, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !30) +!16 = !DISubroutineType(types: !17) +!17 = !{!9, !18} +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !1, line: 1, size: 672, elements: !20) +!20 = !{!21, !22} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !19, file: !1, line: 2, baseType: !9, size: 32) +!22 = !DIDerivedType(tag: DW_TAG_member, name: "dev", scope: !19, file: !1, line: 6, baseType: !23, size: 640, offset: 32) +!23 = !DICompositeType(tag: DW_TAG_array_type, baseType: !24, size: 640, elements: !28) +!24 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !19, file: !1, line: 3, size: 64, elements: !25) +!25 = !{!26, !27} +!26 = !DIDerivedType(tag: DW_TAG_member, name: "dev_id", scope: !24, file: !1, line: 4, baseType: !9, size: 32) +!27 = !DIDerivedType(tag: DW_TAG_member, name: "others", scope: !24, file: !1, line: 5, baseType: !9, size: 32, offset: 32) +!28 = !{!29} +!29 = !DISubrange(count: 10) +!30 = !{!31, !32} +!31 = !DILocalVariable(name: "ctx", arg: 1, scope: !15, file: !1, line: 12, type: !18) +!32 = !DILocalVariable(name: "dev_id", scope: !15, file: !1, line: 13, type: !9) +!33 = !DILocation(line: 0, scope: !15) +!34 = !DILocation(line: 13, column: 3, scope: !15) +!35 = !DILocation(line: 14, column: 40, scope: !15) +!36 = !DILocation(line: 14, column: 3, scope: !15) +!37 = !DILocation(line: 15, column: 10, scope: !15) +!38 = !{!39, !39, i64 0} +!39 = !{!"int", !40, i64 0} +!40 = !{!"omnipotent char", !41, i64 0} +!41 = !{!"Simple C/C++ TBAA"} +!42 = !DILocation(line: 16, column: 1, scope: !15) +!43 = !DILocation(line: 15, column: 3, scope: !15) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-struct-array.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-struct-array.ll new file mode 100644 index 00000000000000..b365c85902d214 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-struct-array.ll @@ -0,0 +1,218 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; struct net_device { +; int dev_id; +; int others; +; }; +; struct sk_buff { +; int i; +; struct net_device dev[10]; +; }; +; #define _(x) (__builtin_preserve_access_index(x)) +; static int (*bpf_probe_read)(void *dst, int size, void *unsafe_ptr) +; = (void *) 4; +; +; int bpf_prog(struct sk_buff *ctx) { +; int dev_id; +; bpf_probe_read(&dev_id, sizeof(int), _(&ctx->dev[5].dev_id)); +; return dev_id; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.sk_buff = type { i32, [10 x %struct.net_device] } +%struct.net_device = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @bpf_prog(%struct.sk_buff*) local_unnamed_addr #0 !dbg !15 { + %2 = alloca i32, align 4 + call void @llvm.dbg.value(metadata %struct.sk_buff* %0, metadata !31, metadata !DIExpression()), !dbg !33 + %3 = bitcast i32* %2 to i8*, !dbg !34 + call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %3) #4, !dbg !34 + %4 = tail call [10 x %struct.net_device]* @llvm.preserve.struct.access.index.p0a10s_struct.net_devices.p0s_struct.sk_buffs(%struct.sk_buff* elementtype(%struct.sk_buff) %0, i32 1, i32 1), !dbg !35, !llvm.preserve.access.index !19 + %5 = tail call %struct.net_device* @llvm.preserve.array.access.index.p0s_struct.net_devices.p0a10s_struct.net_devices([10 x %struct.net_device]* elementtype([10 x %struct.net_device]) %4, i32 1, i32 5), !dbg !35, !llvm.preserve.access.index !23 + %6 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.net_devices(%struct.net_device* elementtype(%struct.net_device) %5, i32 0, i32 0), !dbg !35, !llvm.preserve.access.index !24 + %7 = bitcast i32* %6 to i8*, !dbg !35 + %8 = call i32 inttoptr (i64 4 to i32 (i8*, i32, i8*)*)(i8* nonnull %3, i32 4, i8* %7) #4, !dbg !36 + %9 = load i32, i32* %2, align 4, !dbg !37, !tbaa !38 + call void @llvm.dbg.value(metadata i32 %9, metadata !32, metadata !DIExpression()), !dbg !33 + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %3) #4, !dbg !42 + ret i32 %9, !dbg !43 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 172 +; CHECK-NEXT: .long 172 +; CHECK-NEXT: .long 128 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 2) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 84 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 15 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 19 # BTF_KIND_STRUCT(id = 4) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 30 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 37 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 5) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 44 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 7) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 68 # BTF_KIND_FUNC(id = 8) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "sk_buff" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 105 # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "dev" # string offset=11 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=15 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "net_device" # string offset=19 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "dev_id" # string offset=30 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "others" # string offset=37 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=44 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "ctx" # string offset=64 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "bpf_prog" # string offset=68 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=77 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/llvm/test.c" # string offset=83 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "0:1:5:0" # string offset=120 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long {{[0-9]+}} +; CHECK-NEXT: .long {{[0-9]+}} +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 8 # FuncInfo + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 77 # Field reloc section string offset=77 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 120 +; CHECK-NEXT: .long 0 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone +declare [10 x %struct.net_device]* @llvm.preserve.struct.access.index.p0a10s_struct.net_devices.p0s_struct.sk_buffs(%struct.sk_buff*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare %struct.net_device* @llvm.preserve.array.access.index.p0s_struct.net_devices.p0a10s_struct.net_devices([10 x %struct.net_device]*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.net_devices(%struct.net_device*, i32 immarg, i32 immarg) #2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 (trunk 360739) (llvm/trunk 360747)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm") +!2 = !{} +!3 = !{!4} +!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression()) +!5 = distinct !DIGlobalVariable(name: "bpf_probe_read", scope: !0, file: !1, line: 10, type: !6, isLocal: true, isDefinition: true) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !10, !9, !10} +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 9.0.0 (trunk 360739) (llvm/trunk 360747)"} +!15 = distinct !DISubprogram(name: "bpf_prog", scope: !1, file: !1, line: 13, type: !16, scopeLine: 13, flags: DIFlagPrototyped, isLocal: false, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !30) +!16 = !DISubroutineType(types: !17) +!17 = !{!9, !18} +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !1, line: 5, size: 672, elements: !20) +!20 = !{!21, !22} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !19, file: !1, line: 6, baseType: !9, size: 32) +!22 = !DIDerivedType(tag: DW_TAG_member, name: "dev", scope: !19, file: !1, line: 7, baseType: !23, size: 640, offset: 32) +!23 = !DICompositeType(tag: DW_TAG_array_type, baseType: !24, size: 640, elements: !28) +!24 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "net_device", file: !1, line: 1, size: 64, elements: !25) +!25 = !{!26, !27} +!26 = !DIDerivedType(tag: DW_TAG_member, name: "dev_id", scope: !24, file: !1, line: 2, baseType: !9, size: 32) +!27 = !DIDerivedType(tag: DW_TAG_member, name: "others", scope: !24, file: !1, line: 3, baseType: !9, size: 32, offset: 32) +!28 = !{!29} +!29 = !DISubrange(count: 10) +!30 = !{!31, !32} +!31 = !DILocalVariable(name: "ctx", arg: 1, scope: !15, file: !1, line: 13, type: !18) +!32 = !DILocalVariable(name: "dev_id", scope: !15, file: !1, line: 14, type: !9) +!33 = !DILocation(line: 0, scope: !15) +!34 = !DILocation(line: 14, column: 3, scope: !15) +!35 = !DILocation(line: 15, column: 40, scope: !15) +!36 = !DILocation(line: 15, column: 3, scope: !15) +!37 = !DILocation(line: 16, column: 10, scope: !15) +!38 = !{!39, !39, i64 0} +!39 = !{!"int", !40, i64 0} +!40 = !{!"omnipotent char", !41, i64 0} +!41 = !{!"Simple C/C++ TBAA"} +!42 = !DILocation(line: 17, column: 1, scope: !15) +!43 = !DILocation(line: 16, column: 3, scope: !15) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-array.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-array.ll new file mode 100644 index 00000000000000..036e8d0e3fb512 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-array.ll @@ -0,0 +1,101 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source code: +; typedef const int arr_t[7]; +; typedef arr_t __arr; +; typedef __arr _arr; +; struct __s { _arr a; }; +; typedef struct __s s; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const void *addr); +; int test(s *arg) { +; return get_value(_(&arg->a[1])); +; } +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.__s = type { [7 x i32] } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.__s* %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.__s* %arg, metadata !24, metadata !DIExpression()), !dbg !25 + %0 = tail call [7 x i32]* @llvm.preserve.struct.access.index.p0a7i32.p0s_struct.__ss(%struct.__s* elementtype(%struct.__s) %arg, i32 0, i32 0), !dbg !26, !llvm.preserve.access.index !13 + %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a7i32([7 x i32]* elementtype([7 x i32]) %0, i32 1, i32 1), !dbg !26, !llvm.preserve.access.index !19 + %2 = bitcast i32* %1 to i8*, !dbg !26 + %call = tail call i32 @get_value(i8* %2) #4, !dbg !27 + ret i32 %call, !dbg !28 +} + +; CHECK: .cfi_startproc +; CHECK: [[RELOC:.Ltmp[0-9]+]]: +; CHECK: mov64 r2, 4 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long {{[0-9]+}} # BTF_KIND_STRUCT(id = [[TYPE_ID:[0-9]+]]) +; CHECK: .ascii ".text" # string offset=[[SEC_INDEX:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .ascii "0:0:1" # string offset=[[ACCESS_STR:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long [[SEC_INDEX]] # Field reloc section string offset=[[SEC_INDEX]] +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long [[RELOC]] +; CHECK-NEXT: .long [[TYPE_ID]] +; CHECK-NEXT: .long [[ACCESS_STR]] +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i8*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare [7 x i32]* @llvm.preserve.struct.access.index.p0a7i32.p0s_struct.__ss(%struct.__s*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.array.access.index.p0i32.p0a7i32([7 x i32]*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/core-bugs") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 8, type: !8, scopeLine: 8, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !23) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "s", file: !1, line: 5, baseType: !13) +!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__s", file: !1, line: 4, size: 224, elements: !14) +!14 = !{!15} +!15 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !13, file: !1, line: 4, baseType: !16, size: 224) +!16 = !DIDerivedType(tag: DW_TAG_typedef, name: "_arr", file: !1, line: 3, baseType: !17) +!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "__arr", file: !1, line: 2, baseType: !18) +!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "arr_t", file: !1, line: 1, baseType: !19) +!19 = !DICompositeType(tag: DW_TAG_array_type, baseType: !20, size: 224, elements: !21) +!20 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !10) +!21 = !{!22} +!22 = !DISubrange(count: 7) +!23 = !{!24} +!24 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 8, type: !11) +!25 = !DILocation(line: 0, scope: !7) +!26 = !DILocation(line: 9, column: 20, scope: !7) +!27 = !DILocation(line: 9, column: 10, scope: !7) +!28 = !DILocation(line: 9, column: 3, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-struct-2.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-struct-2.ll new file mode 100644 index 00000000000000..551978bdccfafb --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-struct-2.ll @@ -0,0 +1,92 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source code: +; #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record) +; typedef struct { +; int a; +; } __t; +; #pragma clang attribute pop +; +; int test(__t *arg) { return arg->a; } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.__t = type { i32 } + +; Function Attrs: nounwind readonly +define dso_local i32 @test(%struct.__t* readonly %arg) local_unnamed_addr #0 !dbg !13 { +entry: + call void @llvm.dbg.value(metadata %struct.__t* %arg, metadata !18, metadata !DIExpression()), !dbg !19 + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.__ts(%struct.__t* elementtype(%struct.__t) %arg, i32 0, i32 0), !dbg !20, !llvm.preserve.access.index !4 + %1 = load i32, i32* %0, align 4, !dbg !20, !tbaa !21 + ret i32 %1, !dbg !26 +} + +; CHECK: .long 1 # BTF_KIND_TYPEDEF(id = 2) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 +; +; CHECK: .ascii "__t" # string offset=1 +; CHECK: .byte 97 # string offset=5 +; CHECK: .ascii ".text" # string offset=20 +; CHECK: .ascii "0:0" # string offset=26 +; +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 20 # Field reloc section string offset=20 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 0 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.__ts(%struct.__t*, i32, i32) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 5125d1c934efa69ffc1902ce3b8f2f288653a92f)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core_bug") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_typedef, name: "__t", file: !1, line: 4, baseType: !5) +!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !1, line: 2, size: 32, elements: !6) +!6 = !{!7} +!7 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !5, file: !1, line: 3, baseType: !8, size: 32) +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!9 = !{i32 7, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 5125d1c934efa69ffc1902ce3b8f2f288653a92f)"} +!13 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 7, type: !14, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !17) +!14 = !DISubroutineType(types: !15) +!15 = !{!8, !16} +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!17 = !{!18} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !13, file: !1, line: 7, type: !16) +!19 = !DILocation(line: 0, scope: !13) +!20 = !DILocation(line: 7, column: 34, scope: !13) +!21 = !{!22, !23, i64 0} +!22 = !{!"", !23, i64 0} +!23 = !{!"int", !24, i64 0} +!24 = !{!"omnipotent char", !25, i64 0} +!25 = !{!"Simple C/C++ TBAA"} +!26 = !DILocation(line: 7, column: 22, scope: !13) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-struct.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-struct.ll new file mode 100644 index 00000000000000..26ab10cb05690d --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-struct.ll @@ -0,0 +1,94 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source code: +; typedef int _int; +; typedef _int __int; +; struct __s { __int a; __int b; }; +; typedef struct __s _s; +; typedef _s s; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const void *addr); +; int test(s *arg) { +; return get_value(_(&arg->b)); +; } +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.__s = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.__s* %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %struct.__s* %arg, metadata !21, metadata !DIExpression()), !dbg !22 + %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.__ss(%struct.__s* elementtype(%struct.__s) %arg, i32 1, i32 1), !dbg !23, !llvm.preserve.access.index !14 + %1 = bitcast i32* %0 to i8*, !dbg !23 + %call = tail call i32 @get_value(i8* %1) #4, !dbg !24 + ret i32 %call, !dbg !25 +} + +; CHECK: .cfi_startproc +; CHECK: [[RELOC:.Ltmp[0-9]+]]: +; CHECK: mov64 r2, 4 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long {{[0-9]+}} # BTF_KIND_STRUCT(id = [[TYPE_ID:[0-9]+]]) +; CHECK: .ascii ".text" # string offset=[[SEC_STR:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .ascii "0:1" # string offset=[[ACCESS_STR:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long [[SEC_STR]] # Field reloc section string offset={{[0-9]+}} +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long [[RELOC]] +; CHECK-NEXT: .long [[TYPE_ID]] +; CHECK-NEXT: .long [[ACCESS_STR]] +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i8*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.__ss(%struct.__s*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/core-bugs") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 8, type: !8, scopeLine: 8, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !20) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "s", file: !1, line: 5, baseType: !13) +!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "_s", file: !1, line: 4, baseType: !14) +!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__s", file: !1, line: 3, size: 64, elements: !15) +!15 = !{!16, !19} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !14, file: !1, line: 3, baseType: !17, size: 32) +!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 2, baseType: !18) +!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !1, line: 1, baseType: !10) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !14, file: !1, line: 3, baseType: !17, size: 32, offset: 32) +!20 = !{!21} +!21 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 8, type: !11) +!22 = !DILocation(line: 0, scope: !7) +!23 = !DILocation(line: 9, column: 20, scope: !7) +!24 = !DILocation(line: 9, column: 10, scope: !7) +!25 = !DILocation(line: 9, column: 3, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-union-2.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-union-2.ll new file mode 100644 index 00000000000000..c089259b19b8aa --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-union-2.ll @@ -0,0 +1,91 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source code: +; #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record) +; typedef union { +; int a; +; } __t; +; #pragma clang attribute pop +; +; int test(__t *arg) { return arg->a; } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.__t = type { i32 } + +; Function Attrs: nounwind readonly +define dso_local i32 @test(%union.__t* readonly %arg) local_unnamed_addr #0 !dbg !13 { +entry: + call void @llvm.dbg.value(metadata %union.__t* %arg, metadata !18, metadata !DIExpression()), !dbg !19 + %0 = tail call %union.__t* @llvm.preserve.union.access.index.p0s_union.__ts.p0s_union.__ts(%union.__t* %arg, i32 0), !dbg !20, !llvm.preserve.access.index !4 + %a = getelementptr %union.__t, %union.__t* %0, i64 0, i32 0, !dbg !20 + %1 = load i32, i32* %a, align 4, !dbg !20, !tbaa !21 + ret i32 %1, !dbg !24 +} + +; CHECK: .long 1 # BTF_KIND_TYPEDEF(id = 2) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # BTF_KIND_UNION(id = 3) +; CHECK-NEXT: .long 83886081 # 0x5000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 +; +; CHECK: .ascii "__t" # string offset=1 +; CHECK: .byte 97 # string offset=5 +; CHECK: .ascii ".text" # string offset=20 +; CHECK: .ascii "0:0" # string offset=26 +; +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 20 # Field reloc section string offset=20 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 0 + +; Function Attrs: nounwind readnone +declare %union.__t* @llvm.preserve.union.access.index.p0s_union.__ts.p0s_union.__ts(%union.__t*, i32) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readnone speculatable} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 5125d1c934efa69ffc1902ce3b8f2f288653a92f)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core_bug") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_typedef, name: "__t", file: !1, line: 4, baseType: !5) +!5 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !1, line: 2, size: 32, elements: !6) +!6 = !{!7} +!7 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !5, file: !1, line: 3, baseType: !8, size: 32) +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!9 = !{i32 7, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 5125d1c934efa69ffc1902ce3b8f2f288653a92f)"} +!13 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 7, type: !14, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !17) +!14 = !DISubroutineType(types: !15) +!15 = !{!8, !16} +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!17 = !{!18} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !13, file: !1, line: 7, type: !16) +!19 = !DILocation(line: 0, scope: !13) +!20 = !DILocation(line: 7, column: 34, scope: !13) +!21 = !{!22, !22, i64 0} +!22 = !{!"omnipotent char", !23, i64 0} +!23 = !{!"Simple C/C++ TBAA"} +!24 = !DILocation(line: 7, column: 22, scope: !13) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-union.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-union.ll new file mode 100644 index 00000000000000..feee49e522adab --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef-union.ll @@ -0,0 +1,94 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source code: +; typedef int _int; +; typedef _int __int; +; union __s { __int a; __int b; }; +; typedef union __s _s; +; typedef _s s; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const void *addr); +; int test(s *arg) { +; return get_value(_(&arg->b)); +; } +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.__s = type { i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%union.__s* %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata %union.__s* %arg, metadata !21, metadata !DIExpression()), !dbg !22 + %0 = tail call %union.__s* @llvm.preserve.union.access.index.p0s_union.__ss.p0s_union.__ss(%union.__s* %arg, i32 1), !dbg !23, !llvm.preserve.access.index !14 + %1 = bitcast %union.__s* %0 to i8*, !dbg !23 + %call = tail call i32 @get_value(i8* %1) #4, !dbg !24 + ret i32 %call, !dbg !25 +} + +; CHECK: .cfi_startproc +; CHECK: [[RELOC:.Ltmp[0-9]+]]: +; CHECK: mov64 r2, 0 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long {{[0-9]+}} # BTF_KIND_UNION(id = [[TYPE_ID:[0-9]+]]) +; CHECK: .ascii ".text" # string offset=[[SEC_INDEX:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .ascii "0:1" # string offset=[[ACCESS_STR:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long [[SEC_INDEX]] # Field reloc section string offset=[[SEC_INDEX]] +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long [[RELOC]] +; CHECK-NEXT: .long [[TYPE_ID]] +; CHECK-NEXT: .long [[ACCESS_STR]] +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i8*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare %union.__s* @llvm.preserve.union.access.index.p0s_union.__ss.p0s_union.__ss(%union.__s*, i32 immarg) #2 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/core-bugs") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 8, type: !8, scopeLine: 8, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !20) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "s", file: !1, line: 5, baseType: !13) +!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "_s", file: !1, line: 4, baseType: !14) +!14 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "__s", file: !1, line: 3, size: 32, elements: !15) +!15 = !{!16, !19} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !14, file: !1, line: 3, baseType: !17, size: 32) +!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 2, baseType: !18) +!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !1, line: 1, baseType: !10) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !14, file: !1, line: 3, baseType: !17, size: 32) +!20 = !{!21} +!21 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 8, type: !11) +!22 = !DILocation(line: 0, scope: !7) +!23 = !DILocation(line: 9, column: 20, scope: !7) +!24 = !DILocation(line: 9, column: 10, scope: !7) +!25 = !DILocation(line: 9, column: 3, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef.ll new file mode 100644 index 00000000000000..a07cf0a9bd3b40 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-typedef.ll @@ -0,0 +1,115 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; +; Source code: +; struct s { int a; int b; }; +; typedef struct s __s; +; union u { __s c; __s d; }; +; typedef union u __u; +; typedef __u arr_t[7]; +; typedef arr_t __arr; +; +; #define _(x) (__builtin_preserve_access_index(x)) +; int get_value(const void *addr); +; int test(__arr *arg) { +; return get_value(_(&arg[1]->d.b)); +; } +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c +; The offset reloc offset should be 12 from the base "arg". + +target triple = "sbf" + +%union.u = type { %struct.s } +%struct.s = type { i32, i32 } + +; Function Attrs: nounwind +define dso_local i32 @test([7 x %union.u]* %arg) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata [7 x %union.u]* %arg, metadata !28, metadata !DIExpression()), !dbg !29 + %0 = tail call [7 x %union.u]* @llvm.preserve.array.access.index.p0a7s_union.us.p0a7s_union.us([7 x %union.u]* elementtype([7 x %union.u]) %arg, i32 0, i32 1), !dbg !30, !llvm.preserve.access.index !14 + %arraydecay = getelementptr inbounds [7 x %union.u], [7 x %union.u]* %0, i64 0, i64 0, !dbg !30 + %1 = tail call %union.u* @llvm.preserve.union.access.index.p0s_union.us.p0s_union.us(%union.u* %arraydecay, i32 1), !dbg !30, !llvm.preserve.access.index !16 + %d = getelementptr inbounds %union.u, %union.u* %1, i64 0, i32 0, !dbg !30 + %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s* elementtype(%struct.s) %d, i32 1, i32 1), !dbg !30, !llvm.preserve.access.index !20 + %3 = bitcast i32* %2 to i8*, !dbg !30 + %call = tail call i32 @get_value(i8* %3) #4, !dbg !31 + ret i32 %call, !dbg !32 +} + +; CHECK: .cfi_startproc +; CHECK: [[RELOC:.Ltmp[0-9]+]]: +; CHECK: mov64 r2, 12 +; CHECK: add64 r1, r2 +; CHECK: call get_value + +; CHECK: .long {{[0-9]+}} # BTF_KIND_UNION(id = [[TYPE_ID:[0-9]+]]) +; CHECK: .ascii ".text" # string offset=[[SEC_STR:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .ascii "1:1:1" # string offset=[[ACCESS_STR:[0-9]+]] +; CHECK-NEXT: .byte 0 +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long [[SEC_STR:[0-9]+]] # Field reloc section string offset=[[SEC_STR:[0-9]+]] +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long [[RELOC:.Ltmp[0-9]+]] +; CHECK-NEXT: .long [[TYPE_ID:[0-9]+]] +; CHECK-NEXT: .long [[ACCESS_STR:[0-9]+]] +; CHECK-NEXT: .long 0 + +declare dso_local i32 @get_value(i8*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone +declare [7 x %union.u]* @llvm.preserve.array.access.index.p0a7s_union.us.p0a7s_union.us([7 x %union.u]*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare %union.u* @llvm.preserve.union.access.index.p0s_union.us.p0s_union.us(%union.u*, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/core-bugs") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 10, type: !8, scopeLine: 10, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !27) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "__arr", file: !1, line: 6, baseType: !13) +!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "arr_t", file: !1, line: 5, baseType: !14) +!14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !15, size: 448, elements: !25) +!15 = !DIDerivedType(tag: DW_TAG_typedef, name: "__u", file: !1, line: 4, baseType: !16) +!16 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u", file: !1, line: 3, size: 64, elements: !17) +!17 = !{!18, !24} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !16, file: !1, line: 3, baseType: !19, size: 64) +!19 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s", file: !1, line: 2, baseType: !20) +!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 1, size: 64, elements: !21) +!21 = !{!22, !23} +!22 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !20, file: !1, line: 1, baseType: !10, size: 32) +!23 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !20, file: !1, line: 1, baseType: !10, size: 32, offset: 32) +!24 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !16, file: !1, line: 3, baseType: !19, size: 64) +!25 = !{!26} +!26 = !DISubrange(count: 7) +!27 = !{!28} +!28 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 10, type: !11) +!29 = !DILocation(line: 0, scope: !7) +!30 = !DILocation(line: 11, column: 20, scope: !7) +!31 = !DILocation(line: 11, column: 10, scope: !7) +!32 = !DILocation(line: 11, column: 3, scope: !7) diff --git a/llvm/test/CodeGen/SBF/CORE/offset-reloc-union.ll b/llvm/test/CodeGen/SBF/CORE/offset-reloc-union.ll new file mode 100644 index 00000000000000..2f2aa7db4f9771 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/offset-reloc-union.ll @@ -0,0 +1,222 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; Source code: +; union sk_buff { +; int i; +; struct { +; int netid; +; union { +; int dev_id; +; int others; +; } dev; +; } u; +; }; +; #define _(x) (__builtin_preserve_access_index(x)) +; static int (*bpf_probe_read)(void *dst, int size, void *unsafe_ptr) +; = (void *) 4; +; +; int bpf_prog(union sk_buff *ctx) { +; int dev_id; +; bpf_probe_read(&dev_id, sizeof(int), _(&ctx->u.dev.dev_id)); +; return dev_id; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%union.sk_buff = type { %struct.anon } +%struct.anon = type { i32, %union.anon } +%union.anon = type { i32 } + +; Function Attrs: nounwind +define dso_local i32 @bpf_prog(%union.sk_buff*) local_unnamed_addr #0 !dbg !15 { + %2 = alloca i32, align 4 + call void @llvm.dbg.value(metadata %union.sk_buff* %0, metadata !32, metadata !DIExpression()), !dbg !34 + %3 = bitcast i32* %2 to i8*, !dbg !35 + call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %3) #4, !dbg !35 + %4 = tail call %union.sk_buff* @llvm.preserve.union.access.index.p0s_union.sk_buffs.p0s_union.sk_buffs(%union.sk_buff* %0, i32 1), !dbg !36, !llvm.preserve.access.index !19 + %5 = getelementptr inbounds %union.sk_buff, %union.sk_buff* %4, i64 0, i32 0, !dbg !36 + %6 = tail call %union.anon* @llvm.preserve.struct.access.index.p0s_union.anons.p0s_struct.anons(%struct.anon* elementtype(%struct.anon) %5, i32 1, i32 1), !dbg !36, !llvm.preserve.access.index !23 + %7 = tail call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(%union.anon* %6, i32 0), !dbg !36, !llvm.preserve.access.index !27 + %8 = bitcast %union.anon* %7 to i8*, !dbg !36 + %9 = call i32 inttoptr (i64 4 to i32 (i8*, i32, i8*)*)(i8* nonnull %3, i32 4, i8* %8) #4, !dbg !37 + %10 = load i32, i32* %2, align 4, !dbg !38, !tbaa !39 + call void @llvm.dbg.value(metadata i32 %10, metadata !33, metadata !DIExpression()), !dbg !34 + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %3) #4, !dbg !43 + ret i32 %10, !dbg !44 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 168 +; CHECK-NEXT: .long 168 +; CHECK-NEXT: .long 105 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_UNION(id = 2) +; CHECK-NEXT: .long 83886082 # 0x5000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 13 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 4) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 17 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 0 # BTF_KIND_UNION(id = 5) +; CHECK-NEXT: .long 83886082 # 0x5000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 27 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 34 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 6) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 41 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 45 # BTF_KIND_FUNC(id = 7) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "sk_buff" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 105 # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 117 # string offset=11 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=13 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "netid" # string offset=17 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "dev" # string offset=23 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "dev_id" # string offset=27 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "others" # string offset=34 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "ctx" # string offset=41 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "bpf_prog" # string offset=45 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=54 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/llvm/test.c" # string offset=60 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "0:1:1:0" # string offset=97 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long {{[0-9]+}} +; CHECK-NEXT: .long {{[0-9]+}} +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 8 # FuncInfo + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 54 # Field reloc section string offset=54 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 97 +; CHECK-NEXT: .long 0 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone +declare %union.sk_buff* @llvm.preserve.union.access.index.p0s_union.sk_buffs.p0s_union.sk_buffs(%union.sk_buff*, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare %union.anon* @llvm.preserve.struct.access.index.p0s_union.anons.p0s_struct.anons(%struct.anon*, i32 immarg, i32 immarg) #2 + +; Function Attrs: nounwind readnone +declare %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(%union.anon*, i32 immarg) #2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 (trunk 360739) (llvm/trunk 360747)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm") +!2 = !{} +!3 = !{!4} +!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression()) +!5 = distinct !DIGlobalVariable(name: "bpf_probe_read", scope: !0, file: !1, line: 12, type: !6, isLocal: true, isDefinition: true) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !10, !9, !10} +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 9.0.0 (trunk 360739) (llvm/trunk 360747)"} +!15 = distinct !DISubprogram(name: "bpf_prog", scope: !1, file: !1, line: 15, type: !16, scopeLine: 15, flags: DIFlagPrototyped, isLocal: false, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !31) +!16 = !DISubroutineType(types: !17) +!17 = !{!9, !18} +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!19 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "sk_buff", file: !1, line: 1, size: 64, elements: !20) +!20 = !{!21, !22} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !19, file: !1, line: 2, baseType: !9, size: 32) +!22 = !DIDerivedType(tag: DW_TAG_member, name: "u", scope: !19, file: !1, line: 9, baseType: !23, size: 64) +!23 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !19, file: !1, line: 3, size: 64, elements: !24) +!24 = !{!25, !26} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "netid", scope: !23, file: !1, line: 4, baseType: !9, size: 32) +!26 = !DIDerivedType(tag: DW_TAG_member, name: "dev", scope: !23, file: !1, line: 8, baseType: !27, size: 32, offset: 32) +!27 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !23, file: !1, line: 5, size: 32, elements: !28) +!28 = !{!29, !30} +!29 = !DIDerivedType(tag: DW_TAG_member, name: "dev_id", scope: !27, file: !1, line: 6, baseType: !9, size: 32) +!30 = !DIDerivedType(tag: DW_TAG_member, name: "others", scope: !27, file: !1, line: 7, baseType: !9, size: 32) +!31 = !{!32, !33} +!32 = !DILocalVariable(name: "ctx", arg: 1, scope: !15, file: !1, line: 15, type: !18) +!33 = !DILocalVariable(name: "dev_id", scope: !15, file: !1, line: 16, type: !9) +!34 = !DILocation(line: 0, scope: !15) +!35 = !DILocation(line: 16, column: 3, scope: !15) +!36 = !DILocation(line: 17, column: 40, scope: !15) +!37 = !DILocation(line: 17, column: 3, scope: !15) +!38 = !DILocation(line: 18, column: 10, scope: !15) +!39 = !{!40, !40, i64 0} +!40 = !{!"int", !41, i64 0} +!41 = !{!"omnipotent char", !42, i64 0} +!42 = !{!"Simple C/C++ TBAA"} +!43 = !DILocation(line: 19, column: 1, scope: !15) +!44 = !DILocation(line: 18, column: 3, scope: !15) diff --git a/llvm/test/CodeGen/SBF/CORE/simplifypatable-nullptr.ll b/llvm/test/CodeGen/SBF/CORE/simplifypatable-nullptr.ll new file mode 100644 index 00000000000000..162f98a5902fa7 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/simplifypatable-nullptr.ll @@ -0,0 +1,136 @@ +; RUN: llc -sbf-enable-btf-emission -O2 -march=sbf -mcpu=v3 < %s | FileCheck %s +; Source code: +; struct t3 { +; int i; +; } __attribute__((preserve_access_index)); +; struct t2 { +; void *pad; +; struct t3 *f; +; } __attribute__((preserve_access_index)); +; struct t1 { +; void *pad; +; struct t2 *q; +; } __attribute__((preserve_access_index)); +; +; int g; +; int test(struct t1 *p) { +; struct t2 *q = p->q; +; if (q) +; return 0; +; struct t3 *f = q->f; +; if (!f) g = 5; +; return 0; +; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@g = dso_local local_unnamed_addr global i32 0, align 4, !dbg !0 +@"llvm.t2:0:8$0:1" = external global i64, !llvm.preserve.access.index !6 #0 +@"llvm.t1:0:8$0:1" = external global i64, !llvm.preserve.access.index !15 #0 + +; Function Attrs: mustprogress nofree nosync nounwind willreturn +define dso_local i32 @test(ptr noundef readonly %p) local_unnamed_addr #1 !dbg !25 { +entry: + call void @llvm.dbg.value(metadata ptr %p, metadata !30, metadata !DIExpression()), !dbg !33 + %0 = load i64, ptr @"llvm.t1:0:8$0:1", align 8 + %1 = getelementptr i8, ptr %p, i64 %0 + %2 = tail call ptr @llvm.bpf.passthrough.p0.p0(i32 1, ptr %1) + %3 = load ptr, ptr %2, align 8, !dbg !34, !tbaa !35 + call void @llvm.dbg.value(metadata ptr %3, metadata !31, metadata !DIExpression()), !dbg !33 + %tobool.not = icmp eq ptr %3, null, !dbg !40 + br i1 %tobool.not, label %if.end, label %cleanup, !dbg !42 + +; CHECK-LABEL: test +; CHECK: ldxdw r1, [r1 + 8] +; CHECK: jne r1, 0, + +if.end: ; preds = %entry + %4 = load i64, ptr @"llvm.t2:0:8$0:1", align 8 + %5 = getelementptr i8, ptr null, i64 %4 + %6 = tail call ptr @llvm.bpf.passthrough.p0.p0(i32 0, ptr %5) + %7 = load ptr, ptr %6, align 8, !dbg !43, !tbaa !44 + call void @llvm.dbg.value(metadata ptr %7, metadata !32, metadata !DIExpression()), !dbg !33 + %tobool1.not = icmp eq ptr %7, null, !dbg !46 + br i1 %tobool1.not, label %if.then2, label %cleanup, !dbg !48 + +; CHECK: mov64 r1, 8 +; CHECK: ldxdw r1, [r1 + 0] +; CHECK: jne r1, 0, + +if.then2: ; preds = %if.end + store i32 5, ptr @g, align 4, !dbg !49, !tbaa !50 + br label %cleanup, !dbg !52 + +cleanup: ; preds = %if.end, %if.then2, %entry + ret i32 0, !dbg !53 +} + +; Function Attrs: nofree nosync nounwind readnone +declare ptr @llvm.bpf.passthrough.p0.p0(i32, ptr) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { "btf_ama" } +attributes #1 = { mustprogress nofree nosync nounwind willreturn "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #2 = { nofree nosync nounwind readnone } +attributes #3 = { nocallback nofree nosync nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!20, !21, !22, !23} +!llvm.ident = !{!24} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 13, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git ca2be81e34a6d87edb8e555dfac94ab68ee20f70)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/llvm/nullptr", checksumkind: CSK_MD5, checksum: "2c0ea9b3c647baf31f56992f9142b0df") +!4 = !{!0} +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", file: !3, line: 4, size: 128, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "pad", scope: !6, file: !3, line: 5, baseType: !9, size: 64) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "f", scope: !6, file: !3, line: 6, baseType: !11, size: 64, offset: 64) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t3", file: !3, line: 1, size: 32, elements: !13) +!13 = !{!14} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !12, file: !3, line: 2, baseType: !5, size: 32) +!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 8, size: 128, elements: !16) +!16 = !{!17, !18} +!17 = !DIDerivedType(tag: DW_TAG_member, name: "pad", scope: !15, file: !3, line: 9, baseType: !9, size: 64) +!18 = !DIDerivedType(tag: DW_TAG_member, name: "q", scope: !15, file: !3, line: 10, baseType: !19, size: 64, offset: 64) +!19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64) +!20 = !{i32 7, !"Dwarf Version", i32 5} +!21 = !{i32 2, !"Debug Info Version", i32 3} +!22 = !{i32 1, !"wchar_size", i32 4} +!23 = !{i32 7, !"frame-pointer", i32 2} +!24 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git ca2be81e34a6d87edb8e555dfac94ab68ee20f70)"} +!25 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 14, type: !26, scopeLine: 14, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !29) +!26 = !DISubroutineType(types: !27) +!27 = !{!5, !28} +!28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !15, size: 64) +!29 = !{!30, !31, !32} +!30 = !DILocalVariable(name: "p", arg: 1, scope: !25, file: !3, line: 14, type: !28) +!31 = !DILocalVariable(name: "q", scope: !25, file: !3, line: 15, type: !19) +!32 = !DILocalVariable(name: "f", scope: !25, file: !3, line: 18, type: !11) +!33 = !DILocation(line: 0, scope: !25) +!34 = !DILocation(line: 15, column: 21, scope: !25) +!35 = !{!36, !37, i64 8} +!36 = !{!"t1", !37, i64 0, !37, i64 8} +!37 = !{!"any pointer", !38, i64 0} +!38 = !{!"omnipotent char", !39, i64 0} +!39 = !{!"Simple C/C++ TBAA"} +!40 = !DILocation(line: 16, column: 7, scope: !41) +!41 = distinct !DILexicalBlock(scope: !25, file: !3, line: 16, column: 7) +!42 = !DILocation(line: 16, column: 7, scope: !25) +!43 = !DILocation(line: 18, column: 21, scope: !25) +!44 = !{!45, !37, i64 8} +!45 = !{!"t2", !37, i64 0, !37, i64 8} +!46 = !DILocation(line: 19, column: 8, scope: !47) +!47 = distinct !DILexicalBlock(scope: !25, file: !3, line: 19, column: 7) +!48 = !DILocation(line: 19, column: 7, scope: !25) +!49 = !DILocation(line: 19, column: 13, scope: !47) +!50 = !{!51, !51, i64 0} +!51 = !{!"int", !38, i64 0} +!52 = !DILocation(line: 19, column: 11, scope: !47) +!53 = !DILocation(line: 21, column: 1, scope: !25) diff --git a/llvm/test/CodeGen/SBF/CORE/store-addr.ll b/llvm/test/CodeGen/SBF/CORE/store-addr.ll new file mode 100644 index 00000000000000..70290c048e53f0 --- /dev/null +++ b/llvm/test/CodeGen/SBF/CORE/store-addr.ll @@ -0,0 +1,113 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; RUN: opt -passes='default' %s | llvm-dis > %t1 +; RUN: llc -sbf-enable-btf-emission -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -sbf-enable-btf-emission -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s +; Source code: +; struct t { +; int a; +; } __attribute__((preserve_access_index)); +; int foo(void *); +; int test(struct t *arg) { +; long param[1]; +; param[0] = (long)&arg->a; +; return foo(param); +; } +; Compiler flag to generate IR: +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "sbf" + +%struct.t = type { i32 } + +; Function Attrs: nounwind +define dso_local i32 @test(%struct.t* %arg) local_unnamed_addr #0 !dbg !14 { +entry: + %param = alloca [1 x i64], align 8 + call void @llvm.dbg.value(metadata %struct.t* %arg, metadata !22, metadata !DIExpression()), !dbg !27 + %0 = bitcast [1 x i64]* %param to i8*, !dbg !28 + call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #5, !dbg !28 + call void @llvm.dbg.declare(metadata [1 x i64]* %param, metadata !23, metadata !DIExpression()), !dbg !29 + %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ts(%struct.t* elementtype(%struct.t) %arg, i32 0, i32 0), !dbg !30, !llvm.preserve.access.index !18 + %2 = ptrtoint i32* %1 to i64, !dbg !31 + %arrayidx = getelementptr inbounds [1 x i64], [1 x i64]* %param, i64 0, i64 0, !dbg !32 + store i64 %2, i64* %arrayidx, align 8, !dbg !33, !tbaa !34 + %call = call i32 @foo(i8* nonnull %0) #5, !dbg !38 + call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #5, !dbg !39 + ret i32 %call, !dbg !40 +} + +; CHECK: mov64 r[[OFFSET:[0-9]+]], 0 +; CHECK: add64 r1, r[[OFFSET]] +; CHECK: stxdw [r10 - 8], r1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #2 + +; Function Attrs: nounwind readnone +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ts(%struct.t*, i32, i32) #3 + +declare !dbg !5 dso_local i32 @foo(i8*) local_unnamed_addr #4 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #2 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } +attributes #2 = { argmemonly nounwind } +attributes #3 = { nounwind readnone } +attributes #4 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #5 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 4f995959a05ae94cc4f9cc80035f7e4b3ecd2d88)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{} +!3 = !{!4, !5} +!4 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed) +!5 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 4, type: !6, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!6 = !DISubroutineType(types: !7) +!7 = !{!8, !9} +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!10 = !{i32 7, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 4f995959a05ae94cc4f9cc80035f7e4b3ecd2d88)"} +!14 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 5, type: !15, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !21) +!15 = !DISubroutineType(types: !16) +!16 = !{!8, !17} +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64) +!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !1, line: 1, size: 32, elements: !19) +!19 = !{!20} +!20 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !18, file: !1, line: 2, baseType: !8, size: 32) +!21 = !{!22, !23} +!22 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 5, type: !17) +!23 = !DILocalVariable(name: "param", scope: !14, file: !1, line: 6, type: !24) +!24 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 64, elements: !25) +!25 = !{!26} +!26 = !DISubrange(count: 1) +!27 = !DILocation(line: 0, scope: !14) +!28 = !DILocation(line: 6, column: 5, scope: !14) +!29 = !DILocation(line: 6, column: 10, scope: !14) +!30 = !DILocation(line: 7, column: 28, scope: !14) +!31 = !DILocation(line: 7, column: 16, scope: !14) +!32 = !DILocation(line: 7, column: 5, scope: !14) +!33 = !DILocation(line: 7, column: 14, scope: !14) +!34 = !{!35, !35, i64 0} +!35 = !{!"long", !36, i64 0} +!36 = !{!"omnipotent char", !37, i64 0} +!37 = !{!"Simple C/C++ TBAA"} +!38 = !DILocation(line: 8, column: 12, scope: !14) +!39 = !DILocation(line: 9, column: 1, scope: !14) +!40 = !DILocation(line: 8, column: 5, scope: !14) diff --git a/llvm/test/CodeGen/SBF/adjust-opt-icmp5.ll b/llvm/test/CodeGen/SBF/adjust-opt-icmp5.ll new file mode 100644 index 00000000000000..39f38c8499456f --- /dev/null +++ b/llvm/test/CodeGen/SBF/adjust-opt-icmp5.ll @@ -0,0 +1,71 @@ +; RUN: opt -O2 -S -mtriple=sbf %s -o %t1 +; RUN: llc %t1 -o - | FileCheck -check-prefixes=CHECK,CHECK-V1 %s +; RUN: opt -O2 -S -mtriple=sbf %s -o %t1 +; RUN: llc %t1 -mcpu=v3 -o - | FileCheck -check-prefixes=CHECK,CHECK-V3 %s +; +; Source: +; int bar(int); +; int test(int *p) { +; if (*p <= 0 || *p >= 7) +; return 0; +; return bar(*p); +; } +; Compilation flag: +; clang -target bpf -O2 -S -emit-llvm -Xclang -disable-llvm-passes test.c + +; Function Attrs: nounwind +define dso_local i32 @test(i32* noundef %p) #0 { +entry: + %retval = alloca i32, align 4 + %p.addr = alloca i32*, align 8 + store i32* %p, i32** %p.addr, align 8, !tbaa !3 + %0 = load i32*, i32** %p.addr, align 8, !tbaa !3 + %1 = load i32, i32* %0, align 4, !tbaa !7 + %cmp = icmp sle i32 %1, 0 + br i1 %cmp, label %if.then, label %lor.lhs.false + +lor.lhs.false: ; preds = %entry + %2 = load i32*, i32** %p.addr, align 8, !tbaa !3 + %3 = load i32, i32* %2, align 4, !tbaa !7 + %cmp1 = icmp sge i32 %3, 7 + br i1 %cmp1, label %if.then, label %if.end + +if.then: ; preds = %lor.lhs.false, %entry + store i32 0, i32* %retval, align 4 + br label %return + +if.end: ; preds = %lor.lhs.false + %4 = load i32*, i32** %p.addr, align 8, !tbaa !3 + %5 = load i32, i32* %4, align 4, !tbaa !7 + %call = call i32 @bar(i32 noundef %5) + store i32 %call, i32* %retval, align 4 + br label %return + +return: ; preds = %if.end, %if.then + %6 = load i32, i32* %retval, align 4 + ret i32 %6 +} + +; CHECK-LABEL: test +; CHECK-V1: jsgt r[[#]], r[[#]], +; CHECK-V1: jsgt r[[#]], 6, +; CHECK-V3: jslt w[[#]], 1, +; CHECK-V3: jsgt w[[#]], 6, + +declare dso_local i32 @bar(i32 noundef) #1 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"frame-pointer", i32 2} +!2 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 0d37a76d31c05372908908ff2f01fc58bbf575e8)"} +!3 = !{!4, !4, i64 0} +!4 = !{!"any pointer", !5, i64 0} +!5 = !{!"omnipotent char", !6, i64 0} +!6 = !{!"Simple C/C++ TBAA"} +!7 = !{!8, !8, i64 0} +!8 = !{!"int", !5, i64 0} diff --git a/llvm/test/CodeGen/SBF/adjust-opt-icmp6.ll b/llvm/test/CodeGen/SBF/adjust-opt-icmp6.ll new file mode 100644 index 00000000000000..51863589cd86a7 --- /dev/null +++ b/llvm/test/CodeGen/SBF/adjust-opt-icmp6.ll @@ -0,0 +1,71 @@ +; RUN: opt -O2 -S -mtriple=sbf %s -o %t1 +; RUN: llc %t1 -o - | FileCheck -check-prefixes=CHECK,CHECK-V1 %s +; RUN: opt -O2 -S -mtriple=sbf %s -o %t1 +; RUN: llc %t1 -mcpu=v3 -o - | FileCheck -check-prefixes=CHECK,CHECK-V3 %s +; +; Source: +; unsigned bar(unsigned); +; unsigned int test(unsigned *p) { +; if (*p <= 1 || *p >= 7) +; return 0; +; return bar(*p); +; } +; Compilation flag: +; clang -target bpf -O2 -S -emit-llvm -Xclang -disable-llvm-passes test.c + +; Function Attrs: nounwind +define dso_local i32 @test(i32* noundef %p) #0 { +entry: + %retval = alloca i32, align 4 + %p.addr = alloca i32*, align 8 + store i32* %p, i32** %p.addr, align 8, !tbaa !3 + %0 = load i32*, i32** %p.addr, align 8, !tbaa !3 + %1 = load i32, i32* %0, align 4, !tbaa !7 + %cmp = icmp ule i32 %1, 1 + br i1 %cmp, label %if.then, label %lor.lhs.false + +lor.lhs.false: ; preds = %entry + %2 = load i32*, i32** %p.addr, align 8, !tbaa !3 + %3 = load i32, i32* %2, align 4, !tbaa !7 + %cmp1 = icmp uge i32 %3, 7 + br i1 %cmp1, label %if.then, label %if.end + +if.then: ; preds = %lor.lhs.false, %entry + store i32 0, i32* %retval, align 4 + br label %return + +if.end: ; preds = %lor.lhs.false + %4 = load i32*, i32** %p.addr, align 8, !tbaa !3 + %5 = load i32, i32* %4, align 4, !tbaa !7 + %call = call i32 @bar(i32 noundef %5) + store i32 %call, i32* %retval, align 4 + br label %return + +return: ; preds = %if.end, %if.then + %6 = load i32, i32* %retval, align 4 + ret i32 %6 +} + +; CHECK-LABEL: test +; CHECK-V1: jgt r[[#]], r[[#]], +; CHECK-V1: jgt r[[#]], 6, +; CHECK-V3: jlt w[[#]], 2, +; CHECK-V3: jgt w[[#]], 6, + +declare dso_local i32 @bar(i32 noundef) #1 + +attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"frame-pointer", i32 2} +!2 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 2a25e1af85f3138f70888c4c3f359c6a09e3cfe5)"} +!3 = !{!4, !4, i64 0} +!4 = !{!"any pointer", !5, i64 0} +!5 = !{!"omnipotent char", !6, i64 0} +!6 = !{!"Simple C/C++ TBAA"} +!7 = !{!8, !8, i64 0} +!8 = !{!"int", !5, i64 0} diff --git a/llvm/test/CodeGen/SBF/inline_asm.ll b/llvm/test/CodeGen/SBF/inline_asm.ll index 141bc39c4135d0..7a82c58a325997 100644 --- a/llvm/test/CodeGen/SBF/inline_asm.ll +++ b/llvm/test/CodeGen/SBF/inline_asm.ll @@ -34,10 +34,10 @@ entry: %2 = tail call i32 asm sideeffect ".syntax_old $0 = $1 ll", "=r,i"(i64 333333333333) #2 ; CHECK: r1 = 333333333333 ll %3 = call i32 asm sideeffect ".syntax_old $0 = *(u16 *) $1", "=r,*m"(i32* elementtype(i32) nonnull %a) #2 -; CHECK: r1 = *(u16 *) (r10 - 4) +; CHECK: r1 = *(u16 *)(r10 - 4) %4 = call i32 asm sideeffect ".syntax_old $0 = *(u32 *) $1", "=r,*m"(i32* elementtype(i32) getelementptr inbounds ([2 x i32], [2 x i32]* @g, i64 0, i64 1)) #2 ; CHECK: r1 = g ll -; CHECK: r0 = *(u32 *) (r1 + 4) +; CHECK: r0 = *(u32 *)(r1 + 4) call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0) #2 ret i32 %4 } diff --git a/llvm/test/CodeGen/SBF/inlineasm-wreg.ll b/llvm/test/CodeGen/SBF/inlineasm-wreg.ll index 160fbdc16a6534..09782f47dcb1d4 100644 --- a/llvm/test/CodeGen/SBF/inlineasm-wreg.ll +++ b/llvm/test/CodeGen/SBF/inlineasm-wreg.ll @@ -1,9 +1,9 @@ -; RUN: llc < %s -march=sbf -mattr=+alu32 -verify-machineinstrs | FileCheck %s +; RUN: llc < %s -march=sbf -mattr=+alu32 --sbf-output-asm-variant=1 -verify-machineinstrs | FileCheck %s ; Test that %w works as input constraint ; CHECK-LABEL: test_inlineasm_w_input_constraint define dso_local i32 @test_inlineasm_w_input_constraint() { - tail call void asm sideeffect "w0 = $0", "w"(i32 42) + tail call void asm sideeffect ".syntax_old w0 = $0", "w"(i32 42) ; CHECK: w0 = w1 ret i32 42 } @@ -11,7 +11,7 @@ define dso_local i32 @test_inlineasm_w_input_constraint() { ; Test that %w works as output constraint ; CHECK-LABEL: test_inlineasm_w_output_constraint define dso_local i32 @test_inlineasm_w_output_constraint() { - %1 = tail call i32 asm sideeffect "$0 = $1", "=w,i"(i32 42) + %1 = tail call i32 asm sideeffect ".syntax_old $0 = $1", "=w,i"(i32 42) ; CHECK: w0 = 42 ret i32 %1 } diff --git a/llvm/test/CodeGen/SBF/reloc-btf-2.ll b/llvm/test/CodeGen/SBF/reloc-btf-2.ll index 121c930dc759d1..8ef4f010140d06 100644 --- a/llvm/test/CodeGen/SBF/reloc-btf-2.ll +++ b/llvm/test/CodeGen/SBF/reloc-btf-2.ll @@ -1,8 +1,4 @@ -; RUN: llc -march=bpfel -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s -; RUN: llc -march=bpfeb -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s -: TODO: BTF disabled for sbf as of 559ff25f978a675230cc2dbcc18851424ace7fb9. -: TODO: Remove this test when we know BTF is gone for good. -: XFAIL: * +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s ; source code: ; int g __attribute__((section("ids"))) = 4; @@ -24,10 +20,10 @@ define dso_local i32 @test() local_unnamed_addr #0 !dbg !14 { ret i32 %3, !dbg !24 } -; CHECK-RELOC: file format elf64-bpf +; CHECK-RELOC: file format elf64-sbf ; CHECK-RELOC: RELOCATION RECORDS FOR [.BTF]: -; CHECK-RELOC: R_BPF_64_NODYLD32 .bss -; CHECK-RELOC: R_BPF_64_NODYLD32 g +; CHECK-RELOC: R_SBF_64_NODYLD32 s +; CHECK-RELOC: R_SBF_64_NODYLD32 g ; CHECK-RELOC: RELOCATION RECORDS FOR [.BTF.ext]: attributes #0 = { norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/CodeGen/SBF/reloc-btf.ll b/llvm/test/CodeGen/SBF/reloc-btf.ll index aa929257e03999..dbf3ebe92b2040 100644 --- a/llvm/test/CodeGen/SBF/reloc-btf.ll +++ b/llvm/test/CodeGen/SBF/reloc-btf.ll @@ -1,4 +1,4 @@ -; RUN: llc -march=bpfel -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s +; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s ; Function Attrs: norecurse nounwind readnone define dso_local i32 @test() local_unnamed_addr #0 !dbg !7 { @@ -6,12 +6,12 @@ entry: ret i32 0, !dbg !11 } -; CHECK-RELOC: file format elf64-bpf +; CHECK-RELOC: file format elf64-sbf ; CHECK-RELOC: RELOCATION RECORDS FOR [.debug_info]: -; CHECK-RELOC: R_BPF_64_ABS32 .debug_abbrev -; CHECK-RELOC: R_BPF_64_ABS64 .text +; CHECK-RELOC: R_SBF_64_ABS32 .debug_abbrev +; CHECK-RELOC: R_SBF_64_64 ; CHECK-RELOC: RELOCATION RECORDS FOR [.BTF.ext]: -; CHECK-RELOC: R_BPF_64_NODYLD32 .text +; CHECK-RELOC: R_SBF_64_NODYLD32 attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }