BPF: move AbstractMemberAccess and PreserveDIType passes to EP_EarlyAsPossible
Move abstractMemberAccess and PreserveDIType passes as early as
possible, right after clang code generation.
Currently, compiler may transform the above code
p1 = llvm.bpf.builtin.preserve.struct.access(base, 0, 0);
p2 = llvm.bpf.builtin.preserve.struct.access(p1, 1, 2);
a = llvm.bpf.builtin.preserve_field_info(p2, EXIST);
if (a) {
p1 = llvm.bpf.builtin.preserve.struct.access(base, 0, 0);
p2 = llvm.bpf.builtin.preserve.struct.access(p1, 1, 2);
bpf_probe_read(buf, buf_size, p2);
}
to
p1 = llvm.bpf.builtin.preserve.struct.access(base, 0, 0);
p2 = llvm.bpf.builtin.preserve.struct.access(p1, 1, 2);
a = llvm.bpf.builtin.preserve_field_info(p2, EXIST);
if (a) {
bpf_probe_read(buf, buf_size, p2);
}
and eventually assembly code looks like
reloc_exist = 1;
reloc_member_offset = 10; //calculate member offset from base
p2 = base + reloc_member_offset;
if (reloc_exist) {
bpf_probe_read(bpf, buf_size, p2);
}
if during libbpf relocation resolution, reloc_exist is actually
resolved to 0 (not exist), reloc_member_offset relocation cannot
be resolved and will be patched with illegal instruction.
This will cause verifier failure.
This patch attempts to address this issue by do chaining
analysis and replace chains with special globals right
after clang code gen. This will remove the cse possibility
described in the above. The IR typically looks like
%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
for a particular address computation relocation.
But this transformation has another consequence, code sinking
may happen like below:
PHI = <possibly different @preserve_*_access_globals>
%7 = bitcast %struct.sk_buff* %2 to i8*
%8 = getelementptr i8, i8* %7, %6
For such cases, we will not able to generate relocations since
multiple relocations are merged into one.
This patch introduced a passthrough builtin
to prevent such optimization. Looks like inline assembly has more
impact for optimizaiton, e.g., inlining. Using passthrough has
less impact on optimizations.
A new IR pass is introduced at the beginning of target-dependent
IR optimization, which does:
- report fatal error if any reloc global in PHI nodes
- remove all bpf passthrough builtin functions
Changes for existing CORE tests:
- for clang tests, add "-Xclang -disable-llvm-passes" flags to
avoid builtin->reloc_global transformation so the test is still
able to check correctness for clang generated IR.
- for llvm CodeGen/BPF tests, add "opt -O2 <ir_file> | llvm-dis" command
before "llc" command since "opt" is needed to call newly-placed
builtin->reloc_global transformation. Add target triple in the IR
file since "opt" requires it.
- Since target triple is added in IR file, if a test may produce
different results for different endianness, two tests will be
created, one for bpfeb and another for bpfel, e.g., some tests
for relocation of lshift/rshift of bitfields.
- field-reloc-bitfield-1.ll has different relocations compared to
old codes. This is because for the structure in the test,
new code returns struct layout alignment 4 while old code
is 8. Align 8 is more precise and permits double load. With align 4,
the new mechanism uses 4-byte load, so generating different
relocations.
- test intrinsic-transforms.ll is removed. This is used to test
cse on intrinsics so we do not lose metadata. Now metadata is attached
to global and not instruction, it won't get lost with cse.
Differential Revision: https://reviews.llvm.org/D87153
This commit is contained in:
@@ -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))
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)))
|
||||
|
||||
|
||||
@@ -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)))
|
||||
|
||||
|
||||
@@ -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)))
|
||||
|
||||
|
||||
@@ -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)))
|
||||
|
||||
|
||||
@@ -32,4 +32,6 @@ let TargetPrefix = "bpf" in { // All intrinsics start with "llvm.bpf."
|
||||
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]>;
|
||||
}
|
||||
|
||||
@@ -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 *createBPFMIPeepholeTruncElimPass();
|
||||
FunctionPass *createBPFMIPreEmitPeepholePass();
|
||||
FunctionPass *createBPFMIPreEmitCheckingPass();
|
||||
|
||||
void initializeBPFCheckAndAdjustIRPass(PassRegistry&);
|
||||
|
||||
void initializeBPFAbstractMemberAccessPass(PassRegistry&);
|
||||
void initializeBPFPreserveDITypePass(PassRegistry&);
|
||||
void initializeBPFMISimplifyPatchablePass(PassRegistry&);
|
||||
|
||||
@@ -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 @@ public:
|
||||
// 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 @@ private:
|
||||
};
|
||||
|
||||
const DataLayout *DL = nullptr;
|
||||
Module *M = nullptr;
|
||||
|
||||
std::map<std::string, GlobalVariable *> GEPGlobals;
|
||||
// A map to link preserve_*_access_index instrinsic calls.
|
||||
@@ -141,19 +154,19 @@ private:
|
||||
// intrinsics.
|
||||
std::map<CallInst *, CallInfo> 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<CallInst *> &CallList,
|
||||
uint32_t NumOfZerosIndex, uint32_t DIIndex);
|
||||
bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
|
||||
@@ -168,27 +181,31 @@ private:
|
||||
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");
|
||||
|
||||
// Bail out if no debug info.
|
||||
if (M.debug_compile_units().empty())
|
||||
M = F.getParent();
|
||||
if (!M)
|
||||
return false;
|
||||
|
||||
DL = &M.getDataLayout();
|
||||
return doTransformation(M);
|
||||
// Bail out if no debug info.
|
||||
if (M->debug_compile_units().empty())
|
||||
return false;
|
||||
|
||||
DL = &M->getDataLayout();
|
||||
return doTransformation(F);
|
||||
}
|
||||
|
||||
static bool SkipDIDerivedTag(unsigned Tag, bool skipTypedef) {
|
||||
@@ -341,28 +358,27 @@ void BPFAbstractMemberAccess::replaceWithGEP(std::vector<CallInst *> &CallList,
|
||||
}
|
||||
}
|
||||
|
||||
bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Module &M) {
|
||||
bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Function &F) {
|
||||
std::vector<CallInst *> PreserveArrayIndexCalls;
|
||||
std::vector<CallInst *> PreserveUnionIndexCalls;
|
||||
std::vector<CallInst *> PreserveStructIndexCalls;
|
||||
bool Found = false;
|
||||
|
||||
for (Function &F : M)
|
||||
for (auto &BB : F)
|
||||
for (auto &I : BB) {
|
||||
auto *Call = dyn_cast<CallInst>(&I);
|
||||
CallInfo CInfo;
|
||||
if (!IsPreserveDIAccessIndexCall(Call, CInfo))
|
||||
continue;
|
||||
for (auto &BB : F)
|
||||
for (auto &I : BB) {
|
||||
auto *Call = dyn_cast<CallInst>(&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);
|
||||
}
|
||||
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::traceGEP(GetElementPtrInst *GEP, CallInst *Parent,
|
||||
}
|
||||
}
|
||||
|
||||
void BPFAbstractMemberAccess::collectAICallChains(Module &M, Function &F) {
|
||||
void BPFAbstractMemberAccess::collectAICallChains(Function &F) {
|
||||
AIChain.clear();
|
||||
BaseAICalls.clear();
|
||||
|
||||
@@ -938,7 +954,7 @@ MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *Call,
|
||||
|
||||
/// 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 @@ bool BPFAbstractMemberAccess::transformGEPChain(Module &M, CallInst *Call,
|
||||
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 @@ bool BPFAbstractMemberAccess::transformGEPChain(Module &M, CallInst *Call,
|
||||
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 @@ bool BPFAbstractMemberAccess::transformGEPChain(Module &M, CallInst *Call,
|
||||
// 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 @@ bool BPFAbstractMemberAccess::transformGEPChain(Module &M, CallInst *Call,
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class BasicBlock;
|
||||
class Instruction;
|
||||
class Module;
|
||||
|
||||
class BPFCoreSharedInfo {
|
||||
public:
|
||||
enum PatchableRelocKind : uint32_t {
|
||||
@@ -57,6 +61,14 @@ public:
|
||||
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
|
||||
|
||||
130
llvm/lib/Target/BPF/BPFCheckAndAdjustIR.cpp
Normal file
130
llvm/lib/Target/BPF/BPFCheckAndAdjustIR.cpp
Normal file
@@ -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<PHINode>(&I);
|
||||
if (!PN || PN->use_empty())
|
||||
continue;
|
||||
for (int i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
|
||||
auto *GV = dyn_cast<GlobalVariable>(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<CallInst>(&I);
|
||||
if (!Call)
|
||||
continue;
|
||||
auto *GV = dyn_cast<GlobalValue>(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);
|
||||
}
|
||||
@@ -33,58 +33,58 @@ using namespace llvm;
|
||||
|
||||
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");
|
||||
|
||||
// Bail out if no debug info.
|
||||
if (M.debug_compile_units().empty())
|
||||
M = F.getParent();
|
||||
if (!M)
|
||||
return false;
|
||||
|
||||
return doTransformation(M);
|
||||
// Bail out if no debug info.
|
||||
if (M->debug_compile_units().empty())
|
||||
return false;
|
||||
|
||||
return doTransformation(F);
|
||||
}
|
||||
|
||||
bool BPFPreserveDIType::doTransformation(Module &M) {
|
||||
bool BPFPreserveDIType::doTransformation(Function &F) {
|
||||
std::vector<CallInst *> PreserveDITypeCalls;
|
||||
|
||||
for (auto &F : M) {
|
||||
for (auto &BB : F) {
|
||||
for (auto &I : BB) {
|
||||
auto *Call = dyn_cast<CallInst>(&I);
|
||||
if (!Call)
|
||||
continue;
|
||||
for (auto &BB : F) {
|
||||
for (auto &I : BB) {
|
||||
auto *Call = dyn_cast<CallInst>(&I);
|
||||
if (!Call)
|
||||
continue;
|
||||
|
||||
const auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
|
||||
if (!GV)
|
||||
continue;
|
||||
const auto *GV = dyn_cast<GlobalValue>(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);
|
||||
}
|
||||
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 @@ bool BPFPreserveDIType::doTransformation(Module &M) {
|
||||
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++;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTarget() {
|
||||
PassRegistry &PR = *PassRegistry::getPassRegistry();
|
||||
initializeBPFAbstractMemberAccessPass(PR);
|
||||
initializeBPFPreserveDITypePass(PR);
|
||||
initializeBPFCheckAndAdjustIRPass(PR);
|
||||
initializeBPFMIPeepholePass(PR);
|
||||
initializeBPFMIPeepholeTruncElimPass(PR);
|
||||
}
|
||||
@@ -98,6 +99,13 @@ TargetPassConfig *BPFTargetMachine::createPassConfig(PassManagerBase &PM) {
|
||||
}
|
||||
|
||||
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 BPFTargetMachine::adjustPassManager(PassManagerBuilder &Builder) {
|
||||
}
|
||||
|
||||
void BPFPassConfig::addIRPasses() {
|
||||
addPass(createBPFAbstractMemberAccess(&getBPFTargetMachine()));
|
||||
addPass(createBPFPreserveDIType());
|
||||
|
||||
addPass(createBPFCheckAndAdjustIR());
|
||||
TargetPassConfig::addIRPasses();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ add_public_tablegen_target(BPFCommonTableGen)
|
||||
add_llvm_target(BPFCodeGen
|
||||
BPFAbstractMemberAccess.cpp
|
||||
BPFAsmPrinter.cpp
|
||||
BPFCheckAndAdjustIR.cpp
|
||||
BPFFrameLowering.cpp
|
||||
BPFInstrInfo.cpp
|
||||
BPFISelDAGToDAG.cpp
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
126
llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-1-bpfeb.ll
Normal file
126
llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-1-bpfeb.ll
Normal file
@@ -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)
|
||||
@@ -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 @@ entry:
|
||||
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
|
||||
|
||||
124
llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-2-bpfeb.ll
Normal file
124
llvm/test/CodeGen/BPF/CORE/field-reloc-bitfield-2-bpfeb.ll
Normal file
@@ -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)
|
||||
@@ -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 @@ entry:
|
||||
; 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
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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]] }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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]] }
|
||||
|
||||
155
llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-1-bpfeb.ll
Normal file
155
llvm/test/CodeGen/BPF/CORE/intrinsic-fieldinfo-lshift-1-bpfeb.ll
Normal file
@@ -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)
|
||||
@@ -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 @@ entry:
|
||||
|
||||
; 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
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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]] }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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]] }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
263
llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-2-bpfeb.ll
Normal file
263
llvm/test/CodeGen/BPF/CORE/offset-reloc-fieldinfo-2-bpfeb.ll
Normal file
@@ -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)
|
||||
@@ -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 @@ sw.epilog: ; preds = %entry, %sw.bb9, %sw
|
||||
; 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
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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]] }
|
||||
|
||||
|
||||
@@ -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]]] }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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] }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user