-
Notifications
You must be signed in to change notification settings - Fork 10
[CHERI] generate cap for SMUL overflow temporary #126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
e6746ec to
5d96f3a
Compare
This was previously a pointer from AS0 (i32) which trips an assertion later in `getCopyToParts` (called by `LoweCall`) when a capability is copied into that position.
|
Thanks, do you have a test case that this fixes? |
|
To be honest I haven't tested that the resulting assembly is correct, just that the assertion goes away. Here's a snippet for reproducing the assertion: target datalayout = "e-m:e-pf200:64:64:64:32-p:32:32-i64:64-n32-S128-A200-P200-G200"
define zeroext i1 @smulo.i128(i128 signext %v1, i128 signext %v2, ptr %res) {
entry:
%t = call {i128, i1} @llvm.smul.with.overflow.i128(i128 %v1, i128 %v2)
%val = extractvalue {i128, i1} %t, 0
%obit = extractvalue {i128, i1} %t, 1
store i128 %val, ptr %res
ret i1 %obit
}Before: $ llc --filetype=asm --mcpu=cheriot --mtriple=riscv32-unknown-unknown -target-abi cheriot -mattr=+xcheri,+cap-mode < smulo_i128.ll
.text
.attribute 4, 16
.attribute 5, "rv32e2p0_m2p0_c2p0_xcheri0p0"
.file "<stdin>"
llc: /build/source/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:564: void getCopyToParts(llvm::SelectionDAG&, const llvm::SDLoc&, llvm::SDValue, llvm::SDValue*, unsigned int, llvm::MVT, const llvm::Value*, std::optional<unsigned int>, llvm::ISD::NodeType): Assertion `(PartVT.isInteger() || PartVT == MVT::x86mmx) && ValueVT.isInteger() && "Unknown mismatch!"' failed.
PLEASE submit a bug report to https://github.com/CTSRD-CHERI/llvm-project/issues and include the crash backtrace.
Stack dump:
0. Program arguments: llc --filetype=asm --mcpu=cheriot --mtriple=riscv32-unknown-unknown -target-abi cheriot -mattr=+xcheri,+cap-mode
1. Running pass 'Function Pass Manager' on module '<stdin>'.
2. Running pass 'RISC-V DAG->DAG Pattern Instruction Selection' on function '@smulo.i128'
#0 0x00007f1a31f5626e llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /build/source/llvm/lib/Support/Unix/Signals.inc:723:22
zsh: abort (core dumped) llc --filetype=asm --mcpu=cheriot --mtriple=riscv32-unknown-unknown cheriotAfter: $ llc --filetype=asm --mcpu=cheriot --mtriple=riscv32-unknown-unknown -target-abi cheriot -mattr=+xcheri,+cap-mode < smulo_i128.ll
$ echo $?
0Here's the assembly if you're interested: (expand) .text
.attribute 4, 16
.attribute 5, "rv32e2p0_m2p0_c2p0_xcheri0p0"
.file "<stdin>"
.globl smulo.i128 # -- Begin function smulo.i128
.p2align 1
.type smulo.i128,@function
smulo.i128: # @smulo.i128
.cfi_startproc
# %bb.0: # %entry
cincoffset csp, csp, -80
.cfi_def_cfa_offset 80
csc cra, 72(csp) # 8-byte Folded Spill
csc cs0, 64(csp) # 8-byte Folded Spill
.cfi_offset ra, -8
.cfi_offset s0, -16
clw t0, 0(ca0)
clw t1, 4(ca0)
clw t2, 8(ca0)
clw a0, 12(ca0)
clw a4, 0(ca1)
clw a3, 4(ca1)
clw a5, 8(ca1)
clw a1, 12(ca1)
mv s0, a2
csw zero, 60(csp)
csw a1, 20(csp)
csw a5, 16(csp)
csw a3, 12(csp)
csw a4, 8(csp)
csw a0, 36(csp)
csw t2, 32(csp)
csw t1, 28(csp)
cincoffset ca0, csp, 40
cincoffset ca1, csp, 24
cincoffset ca2, csp, 8
cincoffset ca3, csp, 60
csw t0, 24(csp)
.LBB0_1: # %entry
# Label of block must be emitted
auipcc ct2, %cheriot_compartment_hi(__library_import_libcalls___muloti4)
clc ct2, %cheriot_compartment_lo_i(.LBB0_1)(ct2)
cjalr ct2
clw a0, 60(csp)
snez a0, a0
clw a1, 40(csp)
clw a2, 52(csp)
clw a3, 44(csp)
clw a4, 48(csp)
addi a5, s0, 12
sw.ddc a2, (a5)
addi a2, s0, 8
sw.ddc a4, (a2)
addi a2, s0, 4
sw.ddc a3, (a2)
sw.ddc a1, (s0)
clc cra, 72(csp) # 8-byte Folded Reload
clc cs0, 64(csp) # 8-byte Folded Reload
cincoffset csp, csp, 80
cret
.Lfunc_end0:
.size smulo.i128, .Lfunc_end0-smulo.i128
.cfi_endproc
# -- End function
.section ".note.GNU-stack","",@progbits
.section .compartment_imports,"aG",@progbits,__library_import_libcalls___muloti4,comdat
.type __library_import_libcalls___muloti4,@object
.weak __library_import_libcalls___muloti4
.p2align 3, 0x0
__library_import_libcalls___muloti4:
.word __library_export_libcalls___muloti4+1
.word 0
.size __library_import_libcalls___muloti4, 8 |
|
Thanks. It looks as if __uint128 is being passed in a strange way here. It’s on the stack, but each value is passed as an explicit capability argument in the corresponding argument register, rather than as a stack offsets, which is unusual. The output then generates some sw.ddc instructions, which don’t exist in CHERIoT and, if they did, would not be correct here. I’d like to understand what the correct behaviour is here: replacing an assertion failure with generating code that will crash at run time is not ideal. |
|
I'm not able to reproduce this with our clang-20 based compiler. Do you have a reduced test case I could try? |
|
With the clang-20 based compiler, we generate the following code. I haven't tested it but it looks plausible-ish to me: |
|
Closing unless we find another reproducer. |
This was previously a pointer for AS0 (i32) which trips an assertion later in
getCopyToParts(called byLowerCall) when a capability is copied into that position.I was hitting this assertion with
smulo.i128so I think it's the same issue filed here: CTSRD-CHERI#743. Should I have submitted this to the CHERI repo instead? (I will submit it there afterwards anyway if the patch looks sensible here).