compiler: Fix "nowrite" miscompilation for sret functions

This affected e.g. rtio_input_timestamped_data().
This commit is contained in:
David Nadlinger 2022-05-07 21:21:12 +01:00
parent 35f30ddf05
commit 8a7af3f75c
2 changed files with 12 additions and 1 deletions

View File

@ -1409,7 +1409,10 @@ class LLVMIRGenerator:
llfun.args[idx].add_attribute(attr) llfun.args[idx].add_attribute(attr)
if 'nounwind' in insn.target_function().type.flags: if 'nounwind' in insn.target_function().type.flags:
llfun.attributes.add('nounwind') llfun.attributes.add('nounwind')
if 'nowrite' in insn.target_function().type.flags: if 'nowrite' in insn.target_function().type.flags and not is_sret:
# Even if "nowrite" is correct from the user's perspective (doesn't
# access any other memory observable to ARTIQ Python), this isn't
# true on the LLVM IR level for sret return values.
llfun.attributes.add('inaccessiblememonly') llfun.attributes.add('inaccessiblememonly')
return llfun, list(llargs), llarg_attrs, llcallstackptr return llfun, list(llargs), llarg_attrs, llcallstackptr

View File

@ -13,6 +13,14 @@ from artiq.language.types import *
def foo() -> TNone: def foo() -> TNone:
pass pass
# sret nowrite functions shouldn't be marked inaccessiblememonly.
# CHECK-L: ; Function Attrs: nounwind
# CHECK-NEXT-L: declare void @bar({ i32, i64 }* sret)
@syscall(flags={"nounwind", "nowrite"})
def bar() -> TTuple([TInt32, TInt64]):
pass
@kernel @kernel
def entrypoint(): def entrypoint():
foo() foo()
bar()