diff --git a/clang/test/CodeGen/bpf-attr-preserve-access-index-1.c b/clang/test/CodeGen/bpf-attr-preserve-access-index-1.c --- a/clang/test/CodeGen/bpf-attr-preserve-access-index-1.c +++ b/clang/test/CodeGen/bpf-attr-preserve-access-index-1.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define __reloc__ __attribute__((preserve_access_index)) diff --git a/clang/test/CodeGen/bpf-attr-preserve-access-index-2.c b/clang/test/CodeGen/bpf-attr-preserve-access-index-2.c --- a/clang/test/CodeGen/bpf-attr-preserve-access-index-2.c +++ b/clang/test/CodeGen/bpf-attr-preserve-access-index-2.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define __reloc__ __attribute__((preserve_access_index)) diff --git a/clang/test/CodeGen/bpf-attr-preserve-access-index-3.c b/clang/test/CodeGen/bpf-attr-preserve-access-index-3.c --- a/clang/test/CodeGen/bpf-attr-preserve-access-index-3.c +++ b/clang/test/CodeGen/bpf-attr-preserve-access-index-3.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define __reloc__ __attribute__((preserve_access_index)) diff --git a/clang/test/CodeGen/bpf-attr-preserve-access-index-4.c b/clang/test/CodeGen/bpf-attr-preserve-access-index-4.c --- a/clang/test/CodeGen/bpf-attr-preserve-access-index-4.c +++ b/clang/test/CodeGen/bpf-attr-preserve-access-index-4.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define __reloc__ __attribute__((preserve_access_index)) diff --git a/clang/test/CodeGen/bpf-attr-preserve-access-index-5.c b/clang/test/CodeGen/bpf-attr-preserve-access-index-5.c --- a/clang/test/CodeGen/bpf-attr-preserve-access-index-5.c +++ b/clang/test/CodeGen/bpf-attr-preserve-access-index-5.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define __reloc__ __attribute__((preserve_access_index)) diff --git a/clang/test/CodeGen/bpf-attr-preserve-access-index-6.c b/clang/test/CodeGen/bpf-attr-preserve-access-index-6.c --- a/clang/test/CodeGen/bpf-attr-preserve-access-index-6.c +++ b/clang/test/CodeGen/bpf-attr-preserve-access-index-6.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define __reloc__ __attribute__((preserve_access_index)) diff --git a/clang/test/CodeGen/bpf-attr-preserve-access-index-7.c b/clang/test/CodeGen/bpf-attr-preserve-access-index-7.c --- a/clang/test/CodeGen/bpf-attr-preserve-access-index-7.c +++ b/clang/test/CodeGen/bpf-attr-preserve-access-index-7.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define __reloc__ __attribute__((preserve_access_index)) diff --git a/clang/test/CodeGen/bpf-attr-preserve-access-index-8.c b/clang/test/CodeGen/bpf-attr-preserve-access-index-8.c --- a/clang/test/CodeGen/bpf-attr-preserve-access-index-8.c +++ b/clang/test/CodeGen/bpf-attr-preserve-access-index-8.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define __reloc__ __attribute__((preserve_access_index)) diff --git a/clang/test/CodeGen/bpf-preserve-access-index.c b/clang/test/CodeGen/bpf-preserve-access-index.c --- a/clang/test/CodeGen/bpf-preserve-access-index.c +++ b/clang/test/CodeGen/bpf-preserve-access-index.c @@ -1,5 +1,5 @@ -// RUN: %clang %s -target bpfeb -x c -emit-llvm -S -g -O2 -o - | FileCheck --check-prefix=CHECK %s -// RUN: %clang %s -target bpfel -x c -emit-llvm -S -g -O2 -o - | FileCheck --check-prefix=CHECK %s +// RUN: %clang %s -target bpfeb -x c -emit-llvm -S -g -O2 -Xclang -disable-llvm-passes -o - | FileCheck --check-prefix=CHECK %s +// RUN: %clang %s -target bpfel -x c -emit-llvm -S -g -O2 -Xclang -disable-llvm-passes -o - | FileCheck --check-prefix=CHECK %s struct t { int i:1; diff --git a/clang/test/CodeGen/builtin-bpf-btf-type-id.c b/clang/test/CodeGen/builtin-bpf-btf-type-id.c --- a/clang/test/CodeGen/builtin-bpf-btf-type-id.c +++ b/clang/test/CodeGen/builtin-bpf-btf-type-id.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s unsigned test1(int a) { return __builtin_btf_type_id(a, 0); } unsigned test2(int a) { return __builtin_btf_type_id(&a, 0); } diff --git a/clang/test/CodeGen/builtin-preserve-access-index-typedef.c b/clang/test/CodeGen/builtin-preserve-access-index-typedef.c --- a/clang/test/CodeGen/builtin-preserve-access-index-typedef.c +++ b/clang/test/CodeGen/builtin-preserve-access-index-typedef.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record) typedef struct { diff --git a/clang/test/CodeGen/builtins-bpf-preserve-field-info-1.c b/clang/test/CodeGen/builtins-bpf-preserve-field-info-1.c --- a/clang/test/CodeGen/builtins-bpf-preserve-field-info-1.c +++ b/clang/test/CodeGen/builtins-bpf-preserve-field-info-1.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define _(x, y) (__builtin_preserve_field_info((x), (y))) diff --git a/clang/test/CodeGen/builtins-bpf-preserve-field-info-2.c b/clang/test/CodeGen/builtins-bpf-preserve-field-info-2.c --- a/clang/test/CodeGen/builtins-bpf-preserve-field-info-2.c +++ b/clang/test/CodeGen/builtins-bpf-preserve-field-info-2.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define _(x, y) (__builtin_preserve_field_info((x), (y))) diff --git a/clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c b/clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c --- a/clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c +++ b/clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define _(x, y) (__builtin_preserve_type_info((x), (y))) diff --git a/clang/test/CodeGen/builtins-bpf-preserve-field-info-4.c b/clang/test/CodeGen/builtins-bpf-preserve-field-info-4.c --- a/clang/test/CodeGen/builtins-bpf-preserve-field-info-4.c +++ b/clang/test/CodeGen/builtins-bpf-preserve-field-info-4.c @@ -1,5 +1,5 @@ // REQUIRES: bpf-registered-target -// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang -target bpf -emit-llvm -S -g -Xclang -disable-llvm-passes %s -o - | FileCheck %s #define _(x, y) (__builtin_preserve_enum_value((x), (y))) diff --git a/llvm/include/llvm/IR/IntrinsicsBPF.td b/llvm/include/llvm/IR/IntrinsicsBPF.td --- a/llvm/include/llvm/IR/IntrinsicsBPF.td +++ b/llvm/include/llvm/IR/IntrinsicsBPF.td @@ -32,4 +32,6 @@ def int_bpf_preserve_enum_value : GCCBuiltin<"__builtin_bpf_preserve_enum_value">, Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_ptr_ty, llvm_i64_ty], [IntrNoMem]>; + def int_bpf_passthrough : GCCBuiltin<"__builtin_bpf_passthrough">, + Intrinsic<[llvm_any_ty], [llvm_i32_ty, llvm_any_ty], [IntrNoMem]>; } diff --git a/llvm/lib/Target/BPF/BPF.h b/llvm/lib/Target/BPF/BPF.h --- a/llvm/lib/Target/BPF/BPF.h +++ b/llvm/lib/Target/BPF/BPF.h @@ -15,9 +15,10 @@ namespace llvm { class BPFTargetMachine; -ModulePass *createBPFAbstractMemberAccess(BPFTargetMachine *TM); -ModulePass *createBPFPreserveDIType(); +ModulePass *createBPFCheckAndAdjustIR(); +FunctionPass *createBPFAbstractMemberAccess(BPFTargetMachine *TM); +FunctionPass *createBPFPreserveDIType(); FunctionPass *createBPFISelDag(BPFTargetMachine &TM); FunctionPass *createBPFMISimplifyPatchablePass(); FunctionPass *createBPFMIPeepholePass(); @@ -25,6 +26,8 @@ FunctionPass *createBPFMIPreEmitPeepholePass(); FunctionPass *createBPFMIPreEmitCheckingPass(); +void initializeBPFCheckAndAdjustIRPass(PassRegistry&); + void initializeBPFAbstractMemberAccessPass(PassRegistry&); void initializeBPFPreserveDITypePass(PassRegistry&); void initializeBPFMISimplifyPatchablePass(PassRegistry&); diff --git a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp --- a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp +++ b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp @@ -81,6 +81,7 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicsBPF.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/IR/User.h" @@ -93,18 +94,28 @@ namespace llvm { constexpr StringRef BPFCoreSharedInfo::AmaAttr; +uint32_t BPFCoreSharedInfo::SeqNum; + +Instruction *BPFCoreSharedInfo::insertPassThrough(Module *M, BasicBlock *BB, + Instruction *Input, + Instruction *Before) { + Function *Fn = Intrinsic::getDeclaration( + M, Intrinsic::bpf_passthrough, {Input->getType(), Input->getType()}); + Constant *SeqNumVal = ConstantInt::get(Type::getInt32Ty(BB->getContext()), + BPFCoreSharedInfo::SeqNum++); + + auto *NewInst = CallInst::Create(Fn, {SeqNumVal, Input}); + BB->getInstList().insert(Before->getIterator(), NewInst); + return NewInst; +} } // namespace llvm using namespace llvm; namespace { -class BPFAbstractMemberAccess final : public ModulePass { - StringRef getPassName() const override { - return "BPF Abstract Member Access"; - } - - bool runOnModule(Module &M) override; +class BPFAbstractMemberAccess final : public FunctionPass { + bool runOnFunction(Function &F) override; public: static char ID; @@ -112,7 +123,8 @@ // Add optional BPFTargetMachine parameter so that BPF backend can add the phase // with target machine to find out the endianness. The default constructor (without // parameters) is used by the pass manager for managing purposes. - BPFAbstractMemberAccess(BPFTargetMachine *TM = nullptr) : ModulePass(ID), TM(TM) {} + BPFAbstractMemberAccess(BPFTargetMachine *TM = nullptr) + : FunctionPass(ID), TM(TM) {} struct CallInfo { uint32_t Kind; @@ -132,6 +144,7 @@ }; const DataLayout *DL = nullptr; + Module *M = nullptr; std::map GEPGlobals; // A map to link preserve_*_access_index instrinsic calls. @@ -141,19 +154,19 @@ // intrinsics. std::map BaseAICalls; - bool doTransformation(Module &M); + bool doTransformation(Function &F); void traceAICall(CallInst *Call, CallInfo &ParentInfo); void traceBitCast(BitCastInst *BitCast, CallInst *Parent, CallInfo &ParentInfo); void traceGEP(GetElementPtrInst *GEP, CallInst *Parent, CallInfo &ParentInfo); - void collectAICallChains(Module &M, Function &F); + void collectAICallChains(Function &F); bool IsPreserveDIAccessIndexCall(const CallInst *Call, CallInfo &Cinfo); bool IsValidAIChain(const MDNode *ParentMeta, uint32_t ParentAI, const MDNode *ChildMeta); - bool removePreserveAccessIndexIntrinsic(Module &M); + bool removePreserveAccessIndexIntrinsic(Function &F); void replaceWithGEP(std::vector &CallList, uint32_t NumOfZerosIndex, uint32_t DIIndex); bool HasPreserveFieldInfoCall(CallInfoStack &CallStack); @@ -168,27 +181,31 @@ MDNode *computeAccessKey(CallInst *Call, CallInfo &CInfo, std::string &AccessKey, bool &IsInt32Ret); uint64_t getConstant(const Value *IndexValue); - bool transformGEPChain(Module &M, CallInst *Call, CallInfo &CInfo); + bool transformGEPChain(CallInst *Call, CallInfo &CInfo); }; } // End anonymous namespace char BPFAbstractMemberAccess::ID = 0; INITIALIZE_PASS(BPFAbstractMemberAccess, DEBUG_TYPE, - "abstracting struct/union member accessees", false, false) + "BPF Abstract Member Access", false, false) -ModulePass *llvm::createBPFAbstractMemberAccess(BPFTargetMachine *TM) { +FunctionPass *llvm::createBPFAbstractMemberAccess(BPFTargetMachine *TM) { return new BPFAbstractMemberAccess(TM); } -bool BPFAbstractMemberAccess::runOnModule(Module &M) { +bool BPFAbstractMemberAccess::runOnFunction(Function &F) { LLVM_DEBUG(dbgs() << "********** Abstract Member Accesses **********\n"); + M = F.getParent(); + if (!M) + return false; + // Bail out if no debug info. - if (M.debug_compile_units().empty()) + if (M->debug_compile_units().empty()) return false; - DL = &M.getDataLayout(); - return doTransformation(M); + DL = &M->getDataLayout(); + return doTransformation(F); } static bool SkipDIDerivedTag(unsigned Tag, bool skipTypedef) { @@ -341,28 +358,27 @@ } } -bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Module &M) { +bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Function &F) { std::vector PreserveArrayIndexCalls; std::vector PreserveUnionIndexCalls; std::vector PreserveStructIndexCalls; bool Found = false; - for (Function &F : M) - for (auto &BB : F) - for (auto &I : BB) { - auto *Call = dyn_cast(&I); - CallInfo CInfo; - if (!IsPreserveDIAccessIndexCall(Call, CInfo)) - continue; - - Found = true; - if (CInfo.Kind == BPFPreserveArrayAI) - PreserveArrayIndexCalls.push_back(Call); - else if (CInfo.Kind == BPFPreserveUnionAI) - PreserveUnionIndexCalls.push_back(Call); - else - PreserveStructIndexCalls.push_back(Call); - } + for (auto &BB : F) + for (auto &I : BB) { + auto *Call = dyn_cast(&I); + CallInfo CInfo; + if (!IsPreserveDIAccessIndexCall(Call, CInfo)) + continue; + + Found = true; + if (CInfo.Kind == BPFPreserveArrayAI) + PreserveArrayIndexCalls.push_back(Call); + else if (CInfo.Kind == BPFPreserveUnionAI) + PreserveUnionIndexCalls.push_back(Call); + else + PreserveStructIndexCalls.push_back(Call); + } // do the following transformation: // . addr = preserve_array_access_index(base, dimension, index) @@ -528,7 +544,7 @@ } } -void BPFAbstractMemberAccess::collectAICallChains(Module &M, Function &F) { +void BPFAbstractMemberAccess::collectAICallChains(Function &F) { AIChain.clear(); BaseAICalls.clear(); @@ -938,7 +954,7 @@ /// Call/Kind is the base preserve_*_access_index() call. Attempts to do /// transformation to a chain of relocable GEPs. -bool BPFAbstractMemberAccess::transformGEPChain(Module &M, CallInst *Call, +bool BPFAbstractMemberAccess::transformGEPChain(CallInst *Call, CallInfo &CInfo) { std::string AccessKey; MDNode *TypeMeta; @@ -964,7 +980,7 @@ else VarType = Type::getInt64Ty(BB->getContext()); // 64bit ptr or enum value - GV = new GlobalVariable(M, VarType, false, GlobalVariable::ExternalLinkage, + GV = new GlobalVariable(*M, VarType, false, GlobalVariable::ExternalLinkage, NULL, AccessKey); GV->addAttribute(BPFCoreSharedInfo::AmaAttr); GV->setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta); @@ -980,7 +996,10 @@ LDInst = new LoadInst(Type::getInt32Ty(BB->getContext()), GV, "", Call); else LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call); - Call->replaceAllUsesWith(LDInst); + + Instruction *PassThroughInst = + BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call); + Call->replaceAllUsesWith(PassThroughInst); Call->eraseFromParent(); return true; } @@ -988,7 +1007,7 @@ // For any original GEP Call and Base %2 like // %4 = bitcast %struct.net_device** %dev1 to i64* // it is transformed to: - // %6 = load sk_buff:50:$0:0:0:2:0 + // %6 = load llvm.sk_buff:0:50$0:0:0:2:0 // %7 = bitcast %struct.sk_buff* %2 to i8* // %8 = getelementptr i8, i8* %7, %6 // %9 = bitcast i8* %8 to i64* @@ -1011,24 +1030,69 @@ auto *BCInst2 = new BitCastInst(GEP, Call->getType()); BB->getInstList().insert(Call->getIterator(), BCInst2); - Call->replaceAllUsesWith(BCInst2); + // For the following code, + // Block0: + // ... + // if (...) goto Block1 else ... + // Block1: + // %6 = load llvm.sk_buff:0:50$0:0:0:2:0 + // %7 = bitcast %struct.sk_buff* %2 to i8* + // %8 = getelementptr i8, i8* %7, %6 + // ... + // goto CommonExit + // Block2: + // ... + // if (...) goto Block3 else ... + // Block3: + // %6 = load llvm.bpf_map:0:40$0:0:0:2:0 + // %7 = bitcast %struct.sk_buff* %2 to i8* + // %8 = getelementptr i8, i8* %7, %6 + // ... + // goto CommonExit + // CommonExit + // SimplifyCFG may generate: + // Block0: + // ... + // if (...) goto Block_Common else ... + // Block2: + // ... + // if (...) goto Block_Common else ... + // Block_Common: + // PHI = [llvm.sk_buff:0:50$0:0:0:2:0, llvm.bpf_map:0:40$0:0:0:2:0] + // %6 = load PHI + // %7 = bitcast %struct.sk_buff* %2 to i8* + // %8 = getelementptr i8, i8* %7, %6 + // ... + // goto CommonExit + // For the above code, we cannot perform proper relocation since + // "load PHI" has two possible relocations. + // + // To prevent above tail merging, we use __builtin_bpf_passthrough() + // where one of its parameters is a seq_num. Since two + // __builtin_bpf_passthrough() funcs will always have different seq_num, + // tail merging cannot happen. The __builtin_bpf_passthrough() will be + // removed in the beginning of Target IR passes. + // + // This approach is also used in other places when global var + // representing a relocation is used. + Instruction *PassThroughInst = + BPFCoreSharedInfo::insertPassThrough(M, BB, BCInst2, Call); + Call->replaceAllUsesWith(PassThroughInst); Call->eraseFromParent(); return true; } -bool BPFAbstractMemberAccess::doTransformation(Module &M) { +bool BPFAbstractMemberAccess::doTransformation(Function &F) { bool Transformed = false; - for (Function &F : M) { - // Collect PreserveDIAccessIndex Intrinsic call chains. - // The call chains will be used to generate the access - // patterns similar to GEP. - collectAICallChains(M, F); + // Collect PreserveDIAccessIndex Intrinsic call chains. + // The call chains will be used to generate the access + // patterns similar to GEP. + collectAICallChains(F); - for (auto &C : BaseAICalls) - Transformed = transformGEPChain(M, C.first, C.second) || Transformed; - } + for (auto &C : BaseAICalls) + Transformed = transformGEPChain(C.first, C.second) || Transformed; - return removePreserveAccessIndexIntrinsic(M) || Transformed; + return removePreserveAccessIndexIntrinsic(F) || Transformed; } diff --git a/llvm/lib/Target/BPF/BPFCORE.h b/llvm/lib/Target/BPF/BPFCORE.h --- a/llvm/lib/Target/BPF/BPFCORE.h +++ b/llvm/lib/Target/BPF/BPFCORE.h @@ -13,6 +13,10 @@ namespace llvm { +class BasicBlock; +class Instruction; +class Module; + class BPFCoreSharedInfo { public: enum PatchableRelocKind : uint32_t { @@ -57,6 +61,14 @@ static constexpr StringRef AmaAttr = "btf_ama"; /// The attribute attached to globals representing a type id static constexpr StringRef TypeIdAttr = "btf_type_id"; + + /// llvm.bpf.passthrough builtin seq number + static uint32_t SeqNum; + + /// Insert a bpf passthrough builtin function. + static Instruction *insertPassThrough(Module *M, BasicBlock *BB, + Instruction *Input, + Instruction *Before); }; } // namespace llvm diff --git a/llvm/lib/Target/BPF/BPFCheckAndAdjustIR.cpp b/llvm/lib/Target/BPF/BPFCheckAndAdjustIR.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/BPF/BPFCheckAndAdjustIR.cpp @@ -0,0 +1,130 @@ +//===------------ BPFCheckAndAdjustIR.cpp - Check and Adjust IR -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Check IR and adjust IR for verifier friendly codes. +// The following are done for IR checking: +// - no relocation globals in PHI node. +// The following are done for IR adjustment: +// - remove __builtin_bpf_passthrough builtins. Target independent IR +// optimizations are done and those builtins can be removed. +// +//===----------------------------------------------------------------------===// + +#include "BPF.h" +#include "BPFCORE.h" +#include "BPFTargetMachine.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/User.h" +#include "llvm/IR/Value.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" + +#define DEBUG_TYPE "bpf-check-and-opt-ir" + +using namespace llvm; + +namespace { + +class BPFCheckAndAdjustIR final : public ModulePass { + bool runOnModule(Module &F) override; + +public: + static char ID; + BPFCheckAndAdjustIR() : ModulePass(ID) {} + +private: + void checkIR(Module &M); + bool adjustIR(Module &M); + bool removePassThroughBuiltin(Module &M); +}; +} // End anonymous namespace + +char BPFCheckAndAdjustIR::ID = 0; +INITIALIZE_PASS(BPFCheckAndAdjustIR, DEBUG_TYPE, "BPF Check And Adjust IR", + false, false) + +ModulePass *llvm::createBPFCheckAndAdjustIR() { + return new BPFCheckAndAdjustIR(); +} + +void BPFCheckAndAdjustIR::checkIR(Module &M) { + // Ensure relocation global won't appear in PHI node + // This may happen if the compiler generated the following code: + // B1: + // g1 = @llvm.skb_buff:0:1... + // ... + // goto B_COMMON + // B2: + // g2 = @llvm.skb_buff:0:2... + // ... + // goto B_COMMON + // B_COMMON: + // g = PHI(g1, g2) + // x = load g + // ... + // If anything likes the above "g = PHI(g1, g2)", issue a fatal error. + for (Function &F : M) + for (auto &BB : F) + for (auto &I : BB) { + PHINode *PN = dyn_cast(&I); + if (!PN || PN->use_empty()) + continue; + for (int i = 0, e = PN->getNumIncomingValues(); i < e; ++i) { + auto *GV = dyn_cast(PN->getIncomingValue(i)); + if (!GV) + continue; + if (GV->hasAttribute(BPFCoreSharedInfo::AmaAttr) || + GV->hasAttribute(BPFCoreSharedInfo::TypeIdAttr)) + report_fatal_error("relocation global in PHI node"); + } + } +} + +bool BPFCheckAndAdjustIR::removePassThroughBuiltin(Module &M) { + // Remove __builtin_bpf_passthrough()'s which are used to prevent + // certain IR optimizations. Now major IR optimizations are done, + // remove them. + bool Changed = false; + CallInst *ToBeDeleted = nullptr; + for (Function &F : M) + for (auto &BB : F) + for (auto &I : BB) { + if (ToBeDeleted) { + ToBeDeleted->eraseFromParent(); + ToBeDeleted = nullptr; + } + + auto *Call = dyn_cast(&I); + if (!Call) + continue; + auto *GV = dyn_cast(Call->getCalledOperand()); + if (!GV) + continue; + if (!GV->getName().startswith("llvm.bpf.passthrough")) + continue; + Changed = true; + Value *Arg = Call->getArgOperand(1); + Call->replaceAllUsesWith(Arg); + ToBeDeleted = Call; + } + return Changed; +} + +bool BPFCheckAndAdjustIR::adjustIR(Module &M) { + return removePassThroughBuiltin(M); +} + +bool BPFCheckAndAdjustIR::runOnModule(Module &M) { + checkIR(M); + return adjustIR(M); +} diff --git a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp --- a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp +++ b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp @@ -33,58 +33,58 @@ namespace { -class BPFPreserveDIType final : public ModulePass { - StringRef getPassName() const override { - return "BPF Preserve DebugInfo Type"; - } - - bool runOnModule(Module &M) override; +class BPFPreserveDIType final : public FunctionPass { + bool runOnFunction(Function &F) override; public: static char ID; - BPFPreserveDIType() : ModulePass(ID) {} + BPFPreserveDIType() : FunctionPass(ID) {} private: - bool doTransformation(Module &M); + Module *M = nullptr; + + bool doTransformation(Function &F); }; } // End anonymous namespace char BPFPreserveDIType::ID = 0; -INITIALIZE_PASS(BPFPreserveDIType, DEBUG_TYPE, "preserve debuginfo type", false, - false) +INITIALIZE_PASS(BPFPreserveDIType, DEBUG_TYPE, "BPF Preserve Debuginfo Type", + false, false) -ModulePass *llvm::createBPFPreserveDIType() { return new BPFPreserveDIType(); } +FunctionPass *llvm::createBPFPreserveDIType() { return new BPFPreserveDIType(); } -bool BPFPreserveDIType::runOnModule(Module &M) { +bool BPFPreserveDIType::runOnFunction(Function &F) { LLVM_DEBUG(dbgs() << "********** preserve debuginfo type **********\n"); + M = F.getParent(); + if (!M) + return false; + // Bail out if no debug info. - if (M.debug_compile_units().empty()) + if (M->debug_compile_units().empty()) return false; - return doTransformation(M); + return doTransformation(F); } -bool BPFPreserveDIType::doTransformation(Module &M) { +bool BPFPreserveDIType::doTransformation(Function &F) { std::vector PreserveDITypeCalls; - for (auto &F : M) { - for (auto &BB : F) { - for (auto &I : BB) { - auto *Call = dyn_cast(&I); - if (!Call) - continue; - - const auto *GV = dyn_cast(Call->getCalledOperand()); - if (!GV) - continue; - - if (GV->getName().startswith("llvm.bpf.btf.type.id")) { - if (!Call->getMetadata(LLVMContext::MD_preserve_access_index)) - report_fatal_error( - "Missing metadata for llvm.bpf.btf.type.id intrinsic"); - PreserveDITypeCalls.push_back(Call); - } + for (auto &BB : F) { + for (auto &I : BB) { + auto *Call = dyn_cast(&I); + if (!Call) + continue; + + const auto *GV = dyn_cast(Call->getCalledOperand()); + if (!GV) + continue; + + if (GV->getName().startswith("llvm.bpf.btf.type.id")) { + if (!Call->getMetadata(LLVMContext::MD_preserve_access_index)) + report_fatal_error( + "Missing metadata for llvm.bpf.btf.type.id intrinsic"); + PreserveDITypeCalls.push_back(Call); } } } @@ -118,16 +118,17 @@ IntegerType *VarType = Type::getInt32Ty(BB->getContext()); std::string GVName = BaseName + std::to_string(Count) + "$" + std::to_string(Reloc); - GlobalVariable *GV = - new GlobalVariable(M, VarType, false, GlobalVariable::ExternalLinkage, - NULL, GVName); + GlobalVariable *GV = new GlobalVariable( + *M, VarType, false, GlobalVariable::ExternalLinkage, NULL, GVName); GV->addAttribute(BPFCoreSharedInfo::TypeIdAttr); GV->setMetadata(LLVMContext::MD_preserve_access_index, MD); // Load the global variable which represents the type info. auto *LDInst = new LoadInst(Type::getInt32Ty(BB->getContext()), GV, "", Call); - Call->replaceAllUsesWith(LDInst); + Instruction *PassThroughInst = + BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call); + Call->replaceAllUsesWith(PassThroughInst); Call->eraseFromParent(); Count++; } diff --git a/llvm/lib/Target/BPF/BPFTargetMachine.cpp b/llvm/lib/Target/BPF/BPFTargetMachine.cpp --- a/llvm/lib/Target/BPF/BPFTargetMachine.cpp +++ b/llvm/lib/Target/BPF/BPFTargetMachine.cpp @@ -39,6 +39,7 @@ PassRegistry &PR = *PassRegistry::getPassRegistry(); initializeBPFAbstractMemberAccessPass(PR); initializeBPFPreserveDITypePass(PR); + initializeBPFCheckAndAdjustIRPass(PR); initializeBPFMIPeepholePass(PR); initializeBPFMIPeepholeTruncElimPass(PR); } @@ -98,6 +99,13 @@ } void BPFTargetMachine::adjustPassManager(PassManagerBuilder &Builder) { + Builder.addExtension( + PassManagerBuilder::EP_EarlyAsPossible, + [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { + PM.add(createBPFAbstractMemberAccess(this)); + PM.add(createBPFPreserveDIType()); + }); + Builder.addExtension( PassManagerBuilder::EP_Peephole, [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -107,9 +115,7 @@ } void BPFPassConfig::addIRPasses() { - addPass(createBPFAbstractMemberAccess(&getBPFTargetMachine())); - addPass(createBPFPreserveDIType()); - + addPass(createBPFCheckAndAdjustIR()); TargetPassConfig::addIRPasses(); } diff --git a/llvm/lib/Target/BPF/CMakeLists.txt b/llvm/lib/Target/BPF/CMakeLists.txt --- a/llvm/lib/Target/BPF/CMakeLists.txt +++ b/llvm/lib/Target/BPF/CMakeLists.txt @@ -15,6 +15,7 @@ add_llvm_target(BPFCodeGen BPFAbstractMemberAccess.cpp BPFAsmPrinter.cpp + BPFCheckAndAdjustIR.cpp BPFFrameLowering.cpp BPFInstrInfo.cpp BPFISelDAGToDAG.cpp diff --git a/llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id.ll b/llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id.ll --- a/llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id.ll +++ b/llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; ; Source code: ; static int (*bpf_log)(unsigned tid, void *data, int data_size) = (void *)999; @@ -19,7 +18,9 @@ ; 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 test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" @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 diff --git a/llvm/test/CodeGen/BPF/CORE/field-reloc-alu32.ll b/llvm/test/CodeGen/BPF/CORE/field-reloc-alu32.ll --- a/llvm/test/CodeGen/BPF/CORE/field-reloc-alu32.ll +++ b/llvm/test/CodeGen/BPF/CORE/field-reloc-alu32.ll @@ -1,12 +1,14 @@ -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -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 test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.b = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-1-bpfeb.ll b/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-1-bpfeb.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-1-bpfeb.ll @@ -0,0 +1,126 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK-ALU64 %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EB,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 bpfeb -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpfeb" + +%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* %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: r1 = 20 +; CHECK: r0 = 4 +; CHECK-ALU64: r0 += r1 +; CHECK-ALU32: w0 += w1 +; CHECK-EB: r1 = 45 +; CHECK-ALU64: r0 += r1 +; CHECK-ALU32: 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/BPF/CORE/field-reloc-bitfield-1.ll b/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-1.ll --- a/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU64 %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU32 %s ; Source code: ; struct s { ; unsigned long long f1; @@ -19,7 +18,9 @@ ; __builtin_preserve_field_info(arg->bf2, FIELD_TYPE_LSHIFT_U64); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s = type { i64, i32, i32, i32, i8, i8 } @@ -36,12 +37,11 @@ ret i32 %add1, !dbg !38 } -; CHECK: r1 = 16 -; CHECK: r0 = 8 +; CHECK: r1 = 20 +; CHECK: r0 = 4 ; CHECK-ALU64: r0 += r1 ; CHECK-ALU32: w0 += w1 -; CHECK-EL: r1 = 18 -; CHECK-EB: r1 = 45 +; CHECK-EL: r1 = 50 ; CHECK-ALU64: r0 += r1 ; CHECK-ALU32: w0 += w1 ; CHECK: exit diff --git a/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-2-bpfeb.ll b/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-2-bpfeb.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-2-bpfeb.ll @@ -0,0 +1,124 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK-ALU64 %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EB,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 bpfeb -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpfeb" + +%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* %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: r1 = 2 +; CHECK: r0 = 1 +; CHECK-ALU64: r0 += r1 +; CHECK-ALU32: w0 += w1 +; CHECK-EB: r1 = 61 +; CHECK-ALU64: r0 += r1 +; CHECK-ALU32: 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/BPF/CORE/field-reloc-bitfield-2.ll b/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-2.ll --- a/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU64 %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU32 %s ; Source code: ; struct s { ; char f1; @@ -20,7 +19,9 @@ ; 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 bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s = type <{ i8, i16 }> @@ -42,7 +43,6 @@ ; CHECK-ALU64: r0 += r1 ; CHECK-ALU32: w0 += w1 ; CHECK-EL: r1 = 56 -; CHECK-EB: r1 = 61 ; CHECK-ALU64: r0 += r1 ; CHECK-ALU32: w0 += w1 ; CHECK: exit diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-array-2.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-array-2.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-array-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-array-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s ; Source: ; enum { FIELD_EXISTENCE = 2, }; ; struct s1 { int a1; }; @@ -10,7 +9,9 @@ ; return __builtin_preserve_field_info(v[0], FIELD_EXISTENCE); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s1 = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source code: ; #define _(x) (__builtin_preserve_access_index(x)) @@ -7,7 +8,9 @@ ; 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 test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-1.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-1.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -15,7 +14,9 @@ ; return r1 + r2 + r3 + r4; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { i32 } %struct.s1 = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-2.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-2.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -14,7 +13,9 @@ ; return r1 + r2 + r3; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { %struct.s1 } %struct.s1 = type { i32, i8 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-3.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-3.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-3.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-3.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -13,7 +12,9 @@ ; return r1 + r2; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { %struct.s1 } %struct.s1 = type { [10 x [10 x i32]] } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-4.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-4.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-4.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-byte-size-4.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -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, }; @@ -9,7 +8,9 @@ ; return __builtin_preserve_field_info(arg->a2, FIELD_BYTE_SIZE); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s1 = type { i32, i8, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-1.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-1.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -15,7 +14,9 @@ ; return r1 + r2 + r3 + r4; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s1 = type { i32, i16 } %union.u1 = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-2.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-2.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -13,7 +12,9 @@ ; return r1 + r2; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { %struct.s1 } %struct.s1 = type { i32, i16 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-3.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-3.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-3.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-existence-3.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -12,7 +11,9 @@ ; return r1 + r2; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { %struct.s1 } %struct.s1 = type { [10 x [10 x i32]] } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-1-bpfeb.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-1-bpfeb.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-1-bpfeb.ll @@ -0,0 +1,155 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK-ALU64 %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EB,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 bpfeb -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpfeb" + +%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* %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* %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* %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* %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-EB: r1 = 32 +; CHECK-EB: r0 = 39 +; CHECK-ALU64: r0 += r1 +; CHECK-ALU32: w0 += w1 +; CHECK-EB: r1 = 43 +; CHECK-ALU64: r0 += r1 +; CHECK-ALU32: w0 += w1 +; CHECK-EB: r1 = 48 +; CHECK-ALU64: r0 += r1 +; CHECK-ALU32: 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/BPF/CORE/intrinsic-fieldinfo-lshift-1.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-1.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -16,7 +15,9 @@ ; return r1 + r2 + r3 + r4; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { i32 } %struct.s1 = type { i32 } @@ -47,16 +48,12 @@ ; CHECK-EL: r1 = 57 ; CHECK-EL: r0 = 53 -; CHECK-EB: r1 = 32 -; CHECK-EB: r0 = 39 ; CHECK-ALU64: r0 += r1 ; CHECK-ALU32: w0 += w1 ; CHECK-EL: r1 = 48 -; CHECK-EB: r1 = 43 ; CHECK-ALU64: r0 += r1 ; CHECK-ALU32: w0 += w1 ; CHECK-EL: r1 = 32 -; CHECK-EB: r1 = 48 ; CHECK-ALU64: r0 += r1 ; CHECK-ALU32: w0 += w1 ; CHECK: exit diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-2.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-2.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -14,7 +13,9 @@ ; return r1 + r2; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { %struct.s1 } %struct.s1 = type { i32, i16 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-1.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-1.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -15,7 +14,9 @@ ; return r1 + r2 + r3 + r4; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { i32 } %struct.s1 = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-2.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-2.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -13,7 +12,9 @@ ; return r1 + r2; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { %struct.s1 } %struct.s1 = type { i32, i8 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-3.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-3.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-3.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-rshift-3.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -13,7 +12,9 @@ ; return r1 + r2; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { i32, [24 x i8] } %struct.s1 = type { [5 x [5 x i8]] } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-1.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-1.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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; }; @@ -15,7 +14,9 @@ ; return r1 + r2 + r3 + r4; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s1 = type { i32, i16 } %union.u1 = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-2.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-2.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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 */ @@ -18,7 +17,9 @@ ; return r1 + r2 + r3; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { %struct.s1 } %struct.s1 = type { i32, i16 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-3.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-3.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-3.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-signedness-3.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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, }; @@ -17,7 +16,9 @@ ; return r1 + r2; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u1 = type { %struct.s1 } %struct.s1 = type { [10 x i32], [10 x [10 x i32]] } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-struct.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-struct.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-struct.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-struct.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source code: ; struct s { int a; int b; }; @@ -7,7 +8,9 @@ ; 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 test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-transforms.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-transforms.ll deleted file mode 100644 --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-transforms.ll +++ /dev/null @@ -1,120 +0,0 @@ -; RUN: opt -O2 -march=bpfeb < %s | llvm-dis | FileCheck %s -; RUN: opt -O2 -march=bpfel < %s | llvm-dis | FileCheck %s -; -; Source code: -; #define _(x) (__builtin_preserve_access_index(x)) -; int get_value(const int *arg); -; int test(int b, int *arg) { -; int v1 = b ? get_value(_(&arg[4])) : 0; -; int v2 = b ? get_value(_(&arg[4])) : 0; -; return v1 + v2; -; } -; Compilation flag: -; clang -target bpf -O0 -g -S -emit-llvm -Xclang -disable-O0-optnone test.c - -; Function Attrs: noinline nounwind -define dso_local i32 @test(i32 %b, i32* %arg) #0 !dbg !10 { -entry: - %b.addr = alloca i32, align 4 - %arg.addr = alloca i32*, align 8 - %v1 = alloca i32, align 4 - %v2 = alloca i32, align 4 - store i32 %b, i32* %b.addr, align 4 - call void @llvm.dbg.declare(metadata i32* %b.addr, metadata !13, metadata !DIExpression()), !dbg !14 - store i32* %arg, i32** %arg.addr, align 8 - call void @llvm.dbg.declare(metadata i32** %arg.addr, metadata !15, metadata !DIExpression()), !dbg !16 - call void @llvm.dbg.declare(metadata i32* %v1, metadata !17, metadata !DIExpression()), !dbg !18 - %0 = load i32, i32* %b.addr, align 4, !dbg !19 - %tobool = icmp ne i32 %0, 0, !dbg !19 - br i1 %tobool, label %cond.true, label %cond.false, !dbg !19 - -cond.true: ; preds = %entry - %1 = load i32*, i32** %arg.addr, align 8, !dbg !20 - %2 = call i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32* %1, i32 0, i32 4), !dbg !20, !llvm.preserve.access.index !4 - %3 = bitcast i32* %2 to i8*, !dbg !20 - %4 = bitcast i8* %3 to i32*, !dbg !20 - %call = call i32 @get_value(i32* %4), !dbg !21 - br label %cond.end, !dbg !19 - -cond.false: ; preds = %entry - br label %cond.end, !dbg !19 - -cond.end: ; preds = %cond.false, %cond.true - %cond = phi i32 [ %call, %cond.true ], [ 0, %cond.false ], !dbg !19 - store i32 %cond, i32* %v1, align 4, !dbg !18 - call void @llvm.dbg.declare(metadata i32* %v2, metadata !22, metadata !DIExpression()), !dbg !23 - %5 = load i32, i32* %b.addr, align 4, !dbg !24 - %tobool1 = icmp ne i32 %5, 0, !dbg !24 - br i1 %tobool1, label %cond.true2, label %cond.false4, !dbg !24 - -cond.true2: ; preds = %cond.end - %6 = load i32*, i32** %arg.addr, align 8, !dbg !25 - %7 = call i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32* %6, i32 0, i32 4), !dbg !25, !llvm.preserve.access.index !4 - %8 = bitcast i32* %7 to i8*, !dbg !25 - %9 = bitcast i8* %8 to i32*, !dbg !25 - %call3 = call i32 @get_value(i32* %9), !dbg !26 - br label %cond.end5, !dbg !24 - -; CHECK: tail call i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32* %{{[0-9a-z]+}}, i32 0, i32 4), !dbg !{{[0-9]+}}, !llvm.preserve.access.index !{{[0-9]+}} -; CHECK-NOT: tail call i32* @llvm.preserve.array.access.index - -cond.false4: ; preds = %cond.end - br label %cond.end5, !dbg !24 - -cond.end5: ; preds = %cond.false4, %cond.true2 - %cond6 = phi i32 [ %call3, %cond.true2 ], [ 0, %cond.false4 ], !dbg !24 - store i32 %cond6, i32* %v2, align 4, !dbg !23 - %10 = load i32, i32* %v1, align 4, !dbg !27 - %11 = load i32, i32* %v2, align 4, !dbg !28 - %add = add nsw i32 %10, %11, !dbg !29 - ret i32 %add, !dbg !30 -} - -; Function Attrs: nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - -declare dso_local i32 @get_value(i32*) #2 - -; Function Attrs: nounwind readnone -declare i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32*, i32 immarg, i32 immarg) #3 - -attributes #0 = { 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 #1 = { nounwind readnone speculatable willreturn } -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 } - -!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 (https://github.com/llvm/llvm-project.git 4618b07fe2cede1b73512d1c260cf4981661f47f)", isOptimized: false, 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 (https://github.com/llvm/llvm-project.git 4618b07fe2cede1b73512d1c260cf4981661f47f)"} -!10 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !11, scopeLine: 3, flags: DIFlagPrototyped, isDefinition: true, unit: !0, retainedNodes: !2) -!11 = !DISubroutineType(types: !12) -!12 = !{!5, !5, !4} -!13 = !DILocalVariable(name: "b", arg: 1, scope: !10, file: !1, line: 3, type: !5) -!14 = !DILocation(line: 3, column: 14, scope: !10) -!15 = !DILocalVariable(name: "arg", arg: 2, scope: !10, file: !1, line: 3, type: !4) -!16 = !DILocation(line: 3, column: 22, scope: !10) -!17 = !DILocalVariable(name: "v1", scope: !10, file: !1, line: 4, type: !5) -!18 = !DILocation(line: 4, column: 7, scope: !10) -!19 = !DILocation(line: 4, column: 12, scope: !10) -!20 = !DILocation(line: 4, column: 26, scope: !10) -!21 = !DILocation(line: 4, column: 16, scope: !10) -!22 = !DILocalVariable(name: "v2", scope: !10, file: !1, line: 5, type: !5) -!23 = !DILocation(line: 5, column: 7, scope: !10) -!24 = !DILocation(line: 5, column: 12, scope: !10) -!25 = !DILocation(line: 5, column: 26, scope: !10) -!26 = !DILocation(line: 5, column: 16, scope: !10) -!27 = !DILocation(line: 6, column: 10, scope: !10) -!28 = !DILocation(line: 6, column: 15, scope: !10) -!29 = !DILocation(line: 6, column: 13, scope: !10) -!30 = !DILocation(line: 6, column: 3, scope: !10) diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-enum-value.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-enum-value.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-enum-value.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-enum-value.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source: ; enum AA { VAL1 = -100, VAL2 = 0xffff8000 }; @@ -10,7 +11,9 @@ ; __builtin_preserve_enum_value(*(__BB *)VAL10, 1); ; } ; Compiler flag to generate IR: -; clang -target bpf -S -O2 -g -emit-llvm t1.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes t1.c + +target triple = "bpf" @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 diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-exist.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-exist.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-exist.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-exist.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source: ; enum AA { VAL = 100 }; @@ -11,7 +12,9 @@ ; __builtin_preserve_type_info(*(enum AA *)0, 0); ; } ; Compiler flag to generate IR: -; clang -target bpf -S -O2 -g -emit-llvm t1.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes t1.c + +target triple = "bpf" ; Function Attrs: nounwind readnone define dso_local i32 @test() local_unnamed_addr #0 !dbg !17 { diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-size-1.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-size-1.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-size-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-size-1.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source: ; enum AA { VAL = 100 }; @@ -11,7 +12,9 @@ ; __builtin_preserve_type_info(*(enum AA *)0, 1); ; } ; Compiler flag to generate IR: -; clang -target bpf -S -O2 -g -emit-llvm t1.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes t1.c + +target triple = "bpf" ; Function Attrs: nounwind readnone define dso_local i32 @test() local_unnamed_addr #0 !dbg !17 { diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-size-2.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-size-2.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-size-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-typeinfo-type-size-2.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source: ; enum AA { VAL = 100 }; @@ -14,7 +15,9 @@ ; __builtin_preserve_type_info(a, 1); ; } ; Compiler flag to generate IR: -; clang -target bpf -S -O2 -g -emit-llvm t1.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes t1.c + +target triple = "bpf" ; Function Attrs: nounwind readnone define dso_local i32 @test() local_unnamed_addr #0 !dbg !17 { diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-union.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-union.ll --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-union.ll +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-union.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source code: ; union u { int a; int b; }; @@ -7,7 +8,9 @@ ; 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 test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.u = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/no-elf-ama-symbol.ll b/llvm/test/CodeGen/BPF/CORE/no-elf-ama-symbol.ll --- a/llvm/test/CodeGen/BPF/CORE/no-elf-ama-symbol.ll +++ b/llvm/test/CodeGen/BPF/CORE/no-elf-ama-symbol.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=obj -o - %s | llvm-readelf -s - | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=obj -o - %s | llvm-readelf -s - | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -filetype=obj -addrsig -o - %s | llvm-readelf -s - | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=obj -addrsig -o - %s | llvm-readelf -s - | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=obj -o - %t1 | llvm-readelf -s - | FileCheck -check-prefixes=CHECK %s +; RUN: llc -filetype=obj -addrsig -o - %t1 | llvm-readelf -s - | FileCheck -check-prefixes=CHECK %s ; ; Source Code: ; struct tt { int a; } __attribute__((preserve_access_index)); @@ -9,7 +8,9 @@ ; return arg->a; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm t.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes t.c + +target triple = "bpf" %struct.tt = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/no-narrow-load.ll b/llvm/test/CodeGen/BPF/CORE/no-narrow-load.ll --- a/llvm/test/CodeGen/BPF/CORE/no-narrow-load.ll +++ b/llvm/test/CodeGen/BPF/CORE/no-narrow-load.ll @@ -1,5 +1,5 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; struct data_t { ; int d1; @@ -20,7 +20,9 @@ ; output(&data); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.info_t = type { i32, i32 } %struct.data_t = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-access-str.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-access-str.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-access-str.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-access-str.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source code: ; struct s { int a; int b; }; @@ -11,7 +10,9 @@ ; int test(struct s *arg1, struct t *arg2) { ; return get_value(_(&arg1->b), _(&arg2->d)); ; } -; clang -target bpf -S -O2 -g -emit-llvm test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s = type { i32, i32 } %struct.t = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-basic.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-basic.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-basic.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-basic.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; struct sk_buff { ; int i; @@ -17,7 +16,9 @@ ; return dev != 0; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.sk_buff = type { i32, %struct.net_device* } %struct.net_device = type opaque diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-1.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; struct v1 {int a; int b;}; ; typedef struct v1 __v1; @@ -14,7 +13,9 @@ ; return get_value(_(&cast_to_arr(&arg->d[0])[0][2].b)); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i8, [100 x i32] } %struct.v1 = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-2.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; struct v1 {int a; int b;}; ; typedef struct v1 __v1; @@ -14,7 +13,9 @@ ; return get_value(_(&cast_to_arr(&arg->d[0])[0][2][3].b)); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i8, [100 x i32] } %struct.v1 = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-1.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -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; }; @@ -13,7 +12,9 @@ ; return get_value(_(&cast_to_v1(&arg->d)->b)); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i8, %struct.v2 } %struct.v2 = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-2.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; struct v1 { int a; int b; }; ; typedef struct v1 __v1; @@ -16,7 +15,9 @@ ; return get_value(_(&cast_to_v1(&arg->d)->b)); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i8, %struct.v2 } %struct.v2 = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-3.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-3.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-3.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-3.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; struct v1 { int a; int b; }; ; typedef struct v1 __v1; @@ -15,7 +14,9 @@ ; return get_value(_(&cast_to_v1(&arg->d[4])->b)); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i8, [40 x i32] } %struct.v1 = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-1.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; union v1 { int a; int b; }; ; typedef union v1 __v1; @@ -16,7 +15,9 @@ ; return get_value(_(&cast_to_v1(&arg->d)->b)); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.v3 = type { %union.v2 } %union.v2 = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-2.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; union v1 { int a; int b; }; ; typedef union v1 __v1; @@ -15,7 +14,9 @@ ; return get_value(_(&cast_to_v1(&arg->d[4])->b)); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.v3 = type { [40 x i32] } %union.v1 = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-end-load.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-end-load.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-end-load.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-end-load.ll @@ -1,12 +1,15 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-ALU32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-ALU64 %s +; RUN: llc -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 test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-end-ret.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-end-ret.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-end-ret.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-end-ret.ll @@ -1,12 +1,15 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -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 test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-1.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-1.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK64 %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK32 %s ; Source code: ; struct s { ; int a; @@ -32,7 +33,9 @@ ; return ull >> __builtin_preserve_field_info(arg->b2, FIELD_RSHIFT_U64); ; } ; Compilation flag: -; clang -target bpfel -O2 -g -S -emit-llvm test.c +; clang -target bpfel -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s = type { i32, i16 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-2-bpfeb.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-2-bpfeb.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-2-bpfeb.ll @@ -0,0 +1,263 @@ +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK64 %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EB,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 bpfeb -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpfeb" + +%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* %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: r{{[0-9]+}} = 4 +; CHECK: r{{[0-9]+}} = 4 +; CHECK-EB: r{{[0-9]+}} <<= 41 +; CHECK64: r{{[0-9]+}} s>>= 60 +; CHECK64: r{{[0-9]+}} >>= 60 +; CHECK32: r{{[0-9]+}} >>= 60 +; CHECK32: r{{[0-9]+}} s>>= 60 +; CHECK: 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/BPF/CORE/offset-reloc-fieldinfo-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-2.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK64 %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK64 %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK32 %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK,CHECK-EB,CHECK32 %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK64 %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK,CHECK-EL,CHECK32 %s ; Source code: ; struct s { ; int a; @@ -36,7 +35,9 @@ ; return ull >> __builtin_preserve_field_info(arg->b2, FIELD_RSHIFT_U64); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.s = type { i32, i16 } @@ -115,7 +116,6 @@ ; CHECK: r{{[0-9]+}} = 4 ; CHECK: r{{[0-9]+}} = 4 ; CHECK-EL: r{{[0-9]+}} <<= 51 -; CHECK-EB: r{{[0-9]+}} <<= 41 ; CHECK64: r{{[0-9]+}} s>>= 60 ; CHECK64: r{{[0-9]+}} >>= 60 ; CHECK32: r{{[0-9]+}} >>= 60 diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-1.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -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)) @@ -11,7 +10,9 @@ ; return get_value(_(&g.b)); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-2.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -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)) @@ -11,7 +10,9 @@ ; return get_value(_(&g[1][2].b)); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-3.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-3.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-3.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-3.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -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)) @@ -11,7 +10,9 @@ ; return get_value(_(&g->b)); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-ignore.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-ignore.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-ignore.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-ignore.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -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); @@ -9,7 +8,9 @@ ; return get_value(_(&arg[4])); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" ; Function Attrs: nounwind define dso_local i32 @test(i32* %arg) local_unnamed_addr #0 !dbg !10 { diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-middle-chain.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-middle-chain.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-middle-chain.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-middle-chain.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; struct t1 { ; int c; @@ -21,7 +20,9 @@ ; test1(ps, pt, pi); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.r1 = type { %struct.s1 } %struct.s1 = type { %struct.t1 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-1.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -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; @@ -11,7 +10,9 @@ ; return get_value(_(&arg[1].b[2][3])); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i32, [4 x [4 x i32]] } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-2.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -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; @@ -11,7 +10,9 @@ ; return get_value(_(&arg[1].b[2][3][2])); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i32, [4 x [4 x [4 x i32]]] } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-multilevel.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-multilevel.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-multilevel.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-multilevel.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; struct net_device { ; int dev_id; @@ -21,7 +20,9 @@ ; return dev_id; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.sk_buff = type { i32, %struct.net_device } %struct.net_device = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-1.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-1.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-1.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -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)) @@ -10,7 +9,9 @@ ; return get_value(_(&arg[1])); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-2.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-2.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -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)) @@ -10,7 +9,9 @@ ; return get_value(_(&arg[1].b)); ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.v3 = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-anonymous.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-anonymous.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-anonymous.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-anonymous.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; struct sk_buff { ; int i; @@ -20,7 +19,9 @@ ; return dev_id; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.sk_buff = type { i32, [10 x %struct.anon] } %struct.anon = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-array.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-array.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-array.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-array.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; struct net_device { ; int dev_id; @@ -21,7 +20,9 @@ ; return dev_id; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.sk_buff = type { i32, [10 x %struct.net_device] } %struct.net_device = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source code: ; typedef const int arr_t[7]; @@ -14,7 +13,9 @@ ; int test(s *arg) { ; return get_value(_(&arg->a[1])); ; } -; clang -target bpf -S -O2 -g -emit-llvm test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.__s = type { [7 x i32] } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct-2.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct-2.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source code: ; #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record) @@ -10,7 +11,9 @@ ; ; int test(__t *arg) { return arg->a; } ; Compiler flag to generate IR: -; clang -target bpf -S -O2 -g -emit-llvm test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.__t = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source code: ; typedef int _int; @@ -14,7 +13,9 @@ ; int test(s *arg) { ; return get_value(_(&arg->b)); ; } -; clang -target bpf -S -O2 -g -emit-llvm test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.__s = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-union-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-union-2.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-union-2.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-union-2.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source code: ; #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record) @@ -10,7 +11,9 @@ ; ; int test(__t *arg) { return arg->a; } ; Compiler flag to generate IR: -; clang -target bpf -S -O2 -g -emit-llvm test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.__t = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-union.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-union.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-union.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-union.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source code: ; typedef int _int; @@ -14,7 +13,9 @@ ; int test(s *arg) { ; return get_value(_(&arg->b)); ; } -; clang -target bpf -S -O2 -g -emit-llvm test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.__s = type { i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; ; Source code: ; struct s { int a; int b; }; @@ -16,9 +15,11 @@ ; int test(__arr *arg) { ; return get_value(_(&arg[1]->d.b)); ; } -; clang -target bpf -S -O2 -g -emit-llvm test.c +; 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 = "bpf" + %union.u = type { %struct.s } %struct.s = type { i32, i32 } diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-union.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-union.ll --- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-union.ll +++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-union.ll @@ -1,7 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -; RUN: llc -march=bpfeb -mattr=+alu32 -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s ; Source code: ; union sk_buff { ; int i; @@ -23,7 +22,9 @@ ; return dev_id; ; } ; Compilation flag: -; clang -target bpf -O2 -g -S -emit-llvm test.c +; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %union.sk_buff = type { %struct.anon } %struct.anon = type { i32, %union.anon } diff --git a/llvm/test/CodeGen/BPF/CORE/store-addr.ll b/llvm/test/CodeGen/BPF/CORE/store-addr.ll --- a/llvm/test/CodeGen/BPF/CORE/store-addr.ll +++ b/llvm/test/CodeGen/BPF/CORE/store-addr.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s -; RUN: llc -march=bpfel -mattr=+alu32 -filetype=asm -o - %s | FileCheck %s +; RUN: opt -O2 %s | llvm-dis > %t1 +; RUN: llc -filetype=asm -o - %t1 | FileCheck %s +; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck %s ; Source code: ; struct t { ; int a; @@ -11,7 +12,9 @@ ; return foo(param); ; } ; Compiler flag to generate IR: -; clang -target bpf -S -O2 -g -emit-llvm test.c +; clang -target bpf -S -O2 -g -emit-llvm -Xclang -disable-llvm-passes test.c + +target triple = "bpf" %struct.t = type { i32 }