From ad873f785d4e04a4cf878a27a414987685f44d0f Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 16 Mar 2023 13:51:33 +0000 Subject: [PATCH] [CHERI-RISC-V] In capability mode compressed move is capability move This ensures that addi 0 is no longer incorrectly compressed to c.cmove in capability mode. The difference here is that addi 0 should clear the capability metadata, but if we compress it c.mv (which behaves as CMove in capability mode) we retain the capability metadata. This commit also adds patterns to ensure that CMove is compressed to c.cmove in capability mode (but not in integer mode). NOTE: this should be restricted to standards-compatible mode only since ISAv8/9 did not define a pattern for compressed cmove. For example, QEMU only supports this when running in standards compliant mode: https://github.com/CTSRD-CHERI/qemu/commit/4f95f3f62a8bcd97d92bbf71ccd24b24301e0bd1 --- llvm/lib/Target/RISCV/RISCVInstrInfoC.td | 2 +- llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td | 11 +++++++++ llvm/test/MC/RISCV/cheri/compressed-move.s | 24 +++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 llvm/test/MC/RISCV/cheri/compressed-move.s diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td index a539e11b95006..a56b6aa2e38a4 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -563,7 +563,7 @@ def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1), } let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1, - isAsCheapAsAMove = 1 in + isAsCheapAsAMove = 1, Predicates = [HasStdExtCOrZca, NotCapMode] in def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2), "c.mv", "$rs1, $rs2">, Sched<[WriteIALU, ReadIALU]>; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td index 8b0bfd05d2778..0c6fe5abe6f71 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td @@ -1131,6 +1131,12 @@ def C_CSDCSP : CCheriStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000> { } } // Predicates = [HasCheri, HasCheriRVC, HasStdExtC, IsCapMode] +let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1, + isAsCheapAsAMove = 1, + Predicates = [HasCheri, HasCheriRVC, HasStdExtCOrZca, IsCapMode] in +def C_CMove : RVInst16CR<0b1000, 0b10, (outs GPCRNoC0:$rs1), (ins GPCRNoC0:$rs2), + "c.cmove", "$rs1, $rs2">, + Sched<[WriteIALU, ReadIALU]>; } // DecoderNamespace = "CapModeOnly_" let Predicates = [HasCheri, HasCheriRVC, HasStdExtC, IsCapMode] in { @@ -1173,6 +1179,11 @@ def : InstAlias<"c.cfsdcsp $rs2, ${imm}(${rs1})", (C_CFSDCSP FPR64:$rs2, CSP:$rs def : InstAlias<"c.cj $offset", (C_J simm12_lsb0:$offset), 0>; } +let Predicates = [HasCheri, HasCheriRVC, HasStdExtCOrZca, IsCapMode] in { +def : CompressPat<(CMove GPCRNoC0:$cs1, GPCRNoC0:$cs2), + (C_CMove GPCRNoC0:$cs1, GPCRNoC0:$cs2)>; +} + //===----------------------------------------------------------------------===// // Pseudo-instructions and codegen patterns //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/RISCV/cheri/compressed-move.s b/llvm/test/MC/RISCV/cheri/compressed-move.s new file mode 100644 index 0000000000000..8eb62b29649e4 --- /dev/null +++ b/llvm/test/MC/RISCV/cheri/compressed-move.s @@ -0,0 +1,24 @@ +## Check that we don't compress addi 0 to c.mv (which is c.cmove for the RISC-V standard capmode) +# RUN: llvm-mc %s -triple=riscv64 -mattr=+c,+xcheri,-cap-mode -riscv-no-aliases \ +# RUN: -show-encoding --defsym=PURECAP=0 | FileCheck %s --check-prefix=INT-MODE +# RUN: llvm-mc %s -triple=riscv64 -mattr=+c,+xcheri,+cap-mode -riscv-no-aliases \ +# RUN: -show-encoding --defsym=PURECAP=1 | FileCheck %s --check-prefix=CAP-MODE + +# TODO-ISAV9-CAPMODE: c.mv a1, a0 # encoding: [0xaa,0x85] +# TODO-ISAV9-INTMODE: c.mv a1, a0 # encoding: [0xaa,0x85] +# CAP-MODE: addi a1, a0, 0 # encoding: [0x93,0x05,0x05,0x00] +# INT-MODE: c.mv a1, a0 # encoding: [0xaa,0x85] +## Should not be compressed to c.cmove for capability mode (only in integer mode). +addi a1, a0, 0 + +# CMove should be compressed for capmode. +# TODO-ISAV9-CAPMODE: cmove ca1, ca0 # encoding: [0xdb,0x05,0xa5,0xfe] +# TODO-ISAV9-INTMODE: cmove ca1, ca0 # encoding: [0xdb,0x05,0xa5,0xfe] +# INT-MODE: cmove ca1, ca0 # encoding: [0xdb,0x05,0xa5,0xfe] +# CAP-MODE: c.cmove ca1, ca0 # encoding: [0xaa,0x85] +cmove ca1, ca0 + +.if PURECAP +# CAP-MODE: c.cmove ca2, ca0 # encoding: [0x2a,0x86] +c.cmove ca2, ca0 +.endif