forked from M-Labs/artiq
syscall: lower nowrite to inaccessiblememonly
In the origin implementation, the `nowrite` flag literally means not writing memory at all.
Due to the usage of flags on certain functions, it results in the same issues found in artiq-zynq after optimization passes. (M-Labs/artiq-zynq#119)
A fix wrote by @dnadlinger can resolve this issue. (c1e46cc7c8
)
This commit is contained in:
parent
6db7280b09
commit
5985f7efb5
@ -84,14 +84,6 @@ class LLVMIRGenerator:
|
||||
self.llobject_map = {}
|
||||
self.phis = []
|
||||
self.empty_metadata = self.llmodule.add_metadata([])
|
||||
self.tbaa_tree = self.llmodule.add_metadata([
|
||||
ll.MetaDataString(self.llmodule, "ARTIQ TBAA")
|
||||
])
|
||||
self.tbaa_nowrite_call = self.llmodule.add_metadata([
|
||||
ll.MetaDataString(self.llmodule, "ref-only function call"),
|
||||
self.tbaa_tree,
|
||||
ll.Constant(lli64, 1)
|
||||
])
|
||||
self.quote_fail_msg = None
|
||||
|
||||
def needs_sret(self, lltyp, may_be_large=True):
|
||||
@ -1207,6 +1199,8 @@ class LLVMIRGenerator:
|
||||
llfun.args[i].add_attribute('byval')
|
||||
if 'nounwind' in insn.target_function().type.flags:
|
||||
llfun.attributes.add('nounwind')
|
||||
if 'nowrite' in insn.target_function().type.flags:
|
||||
llfun.attributes.add('inaccessiblememonly')
|
||||
|
||||
return llfun, list(llargs)
|
||||
|
||||
@ -1364,11 +1358,6 @@ class LLVMIRGenerator:
|
||||
# {} elsewhere.
|
||||
llresult = ll.Constant(llunit, [])
|
||||
|
||||
# Never add TBAA nowrite metadata to a functon with sret!
|
||||
# This leads to miscompilations.
|
||||
if types.is_external_function(functiontyp) and 'nowrite' in functiontyp.flags:
|
||||
llcall.set_metadata('tbaa', self.tbaa_nowrite_call)
|
||||
|
||||
return llresult
|
||||
|
||||
def process_Invoke(self, insn):
|
||||
|
@ -304,7 +304,7 @@ class TExternalFunction(TFunction):
|
||||
mangling rules).
|
||||
:ivar flags: (set of str) function flags.
|
||||
Flag ``nounwind`` means the function never raises an exception.
|
||||
Flag ``nowrite`` means the function never writes any memory
|
||||
Flag ``nowrite`` means the function never accesses any memory
|
||||
that the ARTIQ Python code can observe.
|
||||
:ivar broadcast_across_arrays: (bool)
|
||||
If True, the function is transparently applied element-wise when called
|
||||
|
@ -2,11 +2,11 @@ from artiq.language.core import *
|
||||
from artiq.language.types import *
|
||||
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
@syscall(flags={"nounwind"})
|
||||
def cache_get(key: TStr) -> TList(TInt32):
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
@syscall(flags={"nowrite"})
|
||||
@syscall
|
||||
def cache_put(key: TStr, value: TList(TInt32)) -> TNone:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
@ -4,9 +4,9 @@
|
||||
from artiq.language.core import *
|
||||
from artiq.language.types import *
|
||||
|
||||
# CHECK: call void @foo\(\)(, !dbg !\d+)?, !tbaa !\d+
|
||||
# CHECK: call void @foo\(\)(, !dbg !\d+)?
|
||||
|
||||
# CHECK-L: ; Function Attrs: nounwind
|
||||
# CHECK-L: ; Function Attrs: inaccessiblememonly nounwind
|
||||
# CHECK-NEXT-L: declare void @foo()
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
|
Loading…
Reference in New Issue
Block a user