Skip to content

Commit 51bc109

Browse files
committed
[CHERIoT] Mark CGetOffset as unavailable on CHERIoT, and provide an expansion for it.
1 parent 350a782 commit 51bc109

File tree

4 files changed

+43
-2
lines changed

4 files changed

+43
-2
lines changed

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,10 @@ def HasCheriot
13901390
: Predicate<"Subtarget->hasVendorXCheriot()">,
13911391
AssemblerPredicate<(all_of FeatureVendorXCheriot), "CHERIoT Extension">;
13921392

1393+
def HasNoCheriot : Predicate<"!Subtarget->hasVendorXCheriot()">,
1394+
AssemblerPredicate<(all_of(not FeatureVendorXCheriot)),
1395+
"CHERIoT Extension">;
1396+
13931397
def FeatureRelax
13941398
: SubtargetFeature<"relax", "EnableLinkerRelax", "true",
13951399
"Enable Linker relaxation.">;

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10067,6 +10067,25 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
1006710067
// Expand CFromPtr since the dedicated instruction has been removed.
1006810068
return emitCFromPtrReplacement(DAG, DL, Op.getOperand(1), Op.getOperand(2),
1006910069
Op.getValueType(), XLenVT);
10070+
10071+
case Intrinsic::cheri_cap_offset_get: {
10072+
if (!Subtarget.hasVendorXCheriot())
10073+
return {};
10074+
10075+
// cheri_cap_offset_get is not directly implemented on Cheriot, so expand
10076+
// it to (sub (address_get), (base_get)). We lower this during operation
10077+
// legalization for that the subtraction has an opportunity to be
10078+
// optimized by DAGCombine.
10079+
auto Cap = Op->getOperand(1);
10080+
auto Addr = DAG.getNode(
10081+
ISD::INTRINSIC_WO_CHAIN, DL, XLenVT,
10082+
DAG.getConstant(llvm::Intrinsic::cheri_cap_address_get, DL, XLenVT),
10083+
Cap);
10084+
auto Base = DAG.getNode(
10085+
ISD::INTRINSIC_WO_CHAIN, DL, XLenVT,
10086+
DAG.getConstant(llvm::Intrinsic::cheri_cap_base_get, DL, XLenVT), Cap);
10087+
return DAG.getNode(ISD::SUB, DL, XLenVT, Addr, Base);
10088+
}
1007010089
case Intrinsic::cheri_cap_to_pointer:
1007110090
// Expand CToPtr since the dedicated instruction has been removed.
1007210091
// NB: DDC/PCC relocation has been removed, so we no longer subtract the

llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,6 @@ def CGetLen : Cheri_r<0x3, "cgetlen">;
378378
let mayLoad = true in
379379
def CGetTag : Cheri_r<0x4, "cgettag">;
380380
def CGetSealed : Cheri_r<0x5, "cgetsealed">;
381-
def CGetOffset : Cheri_r<0x6, "cgetoffset">;
382381
def CGetFlags : Cheri_r<0x7, "cgetflags">;
383382
def CGetHigh : Cheri_r<0x17, "cgethigh">;
384383
def CGetTop : Cheri_r<0x18, "cgettop">;
@@ -389,6 +388,10 @@ def PseudoCGetAddr : Pseudo<(outs GPR:$rd), (ins GPCR:$cs1), [],
389388
"cgetaddr", "$rd, $cs1">;
390389
}
391390

391+
let Predicates = [HasCheri, HasNoCheriot] in {
392+
def CGetOffset : Cheri_r<0x6, "cgetoffset">;
393+
}
394+
392395
let Predicates = [HasCheriot] in {
393396
def : InstAlias<"ct.cgetperm $rd, $rs1", (CGetPerm GPR:$rd, GPCR:$rs1)>;
394397
def : InstAlias<"ct.cgettype $rd, $rs1", (CGetType GPR:$rd, GPCR:$rs1)>;
@@ -1408,7 +1411,8 @@ def : PatGpcr<int_cheri_cap_type_get, CGetType>;
14081411
def : PatGpcr<int_cheri_cap_base_get, CGetBase>;
14091412
def : PatGpcr<int_cheri_cap_length_get, CGetLen>;
14101413
def : PatGpcr<riscv_cap_sealed_get, CGetSealed>;
1411-
def : PatGpcr<int_cheri_cap_offset_get, CGetOffset>;
1414+
let Predicates = [HasNoCheriot] in def : PatGpcr<int_cheri_cap_offset_get,
1415+
CGetOffset>;
14121416
def : PatGpcr<int_cheri_cap_flags_get, CGetFlags>;
14131417
def : Pat<(XLenVT (int_cheri_cap_address_get GPCR:$cs1)), (PseudoCGetAddr GPCR:$cs1)>;
14141418
def : PatGpcr<int_cheri_cap_high_get, CGetHigh>;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=riscv32cheriot --mcpu=cheriot -target-abi=cheriot -mattr=+xcheri,+cap-mode,+xcheriot -o - %s | FileCheck %s
3+
4+
define i32 @test1(i8 addrspace(200)* %cap) nounwind {
5+
; CHECK-LABEL: test1:
6+
; CHECK: # %bb.0:
7+
; CHECK-NEXT: ct.cgetbase a1, ca0
8+
; CHECK-NEXT: sub a0, a0, a1
9+
; CHECK-NEXT: ct.cret
10+
%newcap = call i32 @llvm.cheri.cap.offset.get.i32(i8 addrspace(200)* %cap)
11+
ret i32 %newcap
12+
}
13+
14+
declare i32 @llvm.cheri.cap.offset.get.i32(i8 addrspace(200)*)

0 commit comments

Comments
 (0)