Skip to content

Commit 833e9b2

Browse files
alessandrodyonghong-song
authored andcommitted
[BPF] add support for 32 bit registers in inline asm
Add "w" constraint type which allows selecting 32 bit registers. 32 bit registers were added in https://reviews.llvm.org/rGca31c3bb3ff149850b664838fbbc7d40ce571879. Differential Revision: https://reviews.llvm.org/D102118
1 parent 803c52d commit 833e9b2

File tree

6 files changed

+98
-1
lines changed

6 files changed

+98
-1
lines changed

clang/lib/Basic/Targets/BPF.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,14 @@ ArrayRef<Builtin::Info> BPFTargetInfo::getTargetBuiltins() const {
4646
return llvm::makeArrayRef(BuiltinInfo, clang::BPF::LastTSBuiltin -
4747
Builtin::FirstTSBuiltin);
4848
}
49+
50+
bool BPFTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
51+
DiagnosticsEngine &Diags) {
52+
for (const auto &Feature : Features) {
53+
if (Feature == "+alu32") {
54+
HasAlu32 = true;
55+
}
56+
}
57+
58+
return true;
59+
}

clang/lib/Basic/Targets/BPF.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace targets {
2323

2424
class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
2525
static const Builtin::Info BuiltinInfo[];
26+
bool HasAlu32 = false;
2627

2728
public:
2829
BPFTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
@@ -55,6 +56,8 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
5556
bool Enabled) const override {
5657
Features[Name] = Enabled;
5758
}
59+
bool handleTargetFeatures(std::vector<std::string> &Features,
60+
DiagnosticsEngine &Diags) override;
5861

5962
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
6063

@@ -68,7 +71,16 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
6871
ArrayRef<const char *> getGCCRegNames() const override { return None; }
6972

7073
bool validateAsmConstraint(const char *&Name,
71-
TargetInfo::ConstraintInfo &info) const override {
74+
TargetInfo::ConstraintInfo &Info) const override {
75+
switch (*Name) {
76+
default:
77+
break;
78+
case 'w':
79+
if (HasAlu32) {
80+
Info.setAllowsRegister();
81+
}
82+
break;
83+
}
7284
return true;
7385
}
7486

@@ -93,6 +105,10 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
93105
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
94106

95107
bool setCPU(const std::string &Name) override {
108+
if (Name == "v3") {
109+
HasAlu32 = true;
110+
}
111+
96112
StringRef CPUName(Name);
97113
return isValidCPUName(CPUName);
98114
}

clang/test/CodeGen/bpf-inline-asm.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// REQUIRES: bpf-registered-target
2+
// RUN: %clang -target bpf -emit-llvm -S -Xclang -target-feature -Xclang +alu32 %s -o - | FileCheck %s
3+
// RUN: %clang -target bpf -emit-llvm -S -mcpu=v3 %s -o - | FileCheck %s
4+
5+
void test_generic_constraints(int var32, long var64) {
6+
asm("%0 = %1"
7+
: "=r"(var32)
8+
: "0"(var32));
9+
// CHECK: [[R32_ARG:%[a-zA-Z0-9]+]] = load i32, i32*
10+
// CHECK: call i32 asm "$0 = $1", "=r,0"(i32 [[R32_ARG]])
11+
12+
asm("%0 = %1"
13+
: "=r"(var64)
14+
: "0"(var64));
15+
// CHECK: [[R64_ARG:%[a-zA-Z0-9]+]] = load i64, i64*
16+
// CHECK: call i64 asm "$0 = $1", "=r,0"(i64 [[R64_ARG]])
17+
18+
asm("%0 = %1"
19+
: "=r"(var64)
20+
: "r"(var64));
21+
// CHECK: [[R64_ARG:%[a-zA-Z0-9]+]] = load i64, i64*
22+
// CHECK: call i64 asm "$0 = $1", "=r,r"(i64 [[R64_ARG]])
23+
}
24+
25+
void test_constraint_w(int a) {
26+
asm("%0 = %1"
27+
: "=w"(a)
28+
: "w"(a));
29+
// CHECK: [[R32_ARG:%[a-zA-Z0-9]+]] = load i32, i32*
30+
// CHECK: call i32 asm "$0 = $1", "=w,w"(i32 [[R32_ARG]])
31+
}

llvm/lib/Target/BPF/BPFISelLowering.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,20 @@ bool BPFTargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
220220
return NumBits1 == 32 && NumBits2 == 64;
221221
}
222222

223+
BPFTargetLowering::ConstraintType
224+
BPFTargetLowering::getConstraintType(StringRef Constraint) const {
225+
if (Constraint.size() == 1) {
226+
switch (Constraint[0]) {
227+
default:
228+
break;
229+
case 'w':
230+
return C_RegisterClass;
231+
}
232+
}
233+
234+
return TargetLowering::getConstraintType(Constraint);
235+
}
236+
223237
std::pair<unsigned, const TargetRegisterClass *>
224238
BPFTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
225239
StringRef Constraint,
@@ -229,6 +243,10 @@ BPFTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
229243
switch (Constraint[0]) {
230244
case 'r': // GENERAL_REGS
231245
return std::make_pair(0U, &BPF::GPRRegClass);
246+
case 'w':
247+
if (HasAlu32)
248+
return std::make_pair(0U, &BPF::GPR32RegClass);
249+
break;
232250
default:
233251
break;
234252
}

llvm/lib/Target/BPF/BPFISelLowering.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ class BPFTargetLowering : public TargetLowering {
4646
// with the given GlobalAddress is legal.
4747
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
4848

49+
BPFTargetLowering::ConstraintType
50+
getConstraintType(StringRef Constraint) const override;
51+
4952
std::pair<unsigned, const TargetRegisterClass *>
5053
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
5154
StringRef Constraint, MVT VT) const override;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
; RUN: llc < %s -march=bpfel -mattr=+alu32 -verify-machineinstrs | FileCheck %s
2+
; RUN: llc < %s -march=bpfeb -mattr=+alu32 -verify-machineinstrs | FileCheck %s
3+
4+
; Test that %w works as input constraint
5+
; CHECK-LABEL: test_inlineasm_w_input_constraint
6+
define dso_local i32 @test_inlineasm_w_input_constraint() {
7+
tail call void asm sideeffect "w0 = $0", "w"(i32 42)
8+
; CHECK: w0 = w1
9+
ret i32 42
10+
}
11+
12+
; Test that %w works as output constraint
13+
; CHECK-LABEL: test_inlineasm_w_output_constraint
14+
define dso_local i32 @test_inlineasm_w_output_constraint() {
15+
%1 = tail call i32 asm sideeffect "$0 = $1", "=w,i"(i32 42)
16+
; CHECK: w0 = 42
17+
ret i32 %1
18+
}

0 commit comments

Comments
 (0)