(original) (raw)
Jonas Paulsson wrote on 30.11.2017 12:11:56:
> \* This intrinsic only stores and does not load:
>
> � def int\_s390\_tbegin : Intrinsic<\[llvm\_i32\_ty\], \[llvm\_ptr\_ty,
> llvm\_i32\_ty\],
> ��������������������������������� \[IntrNoDuplicate\]>;
>
> ��� let mayLoad = 1 in� // WRONG: does not load
> ����� def TBEGINC : SideEffectBinarySIL<"tbeginc", 0xE561,
> ��������������������������������������� int\_s390\_tbeginc, imm32zx16>;
>
> I tried doing \[IntrNoDuplicate, WriteOnly<0>\], but found that for some
> reason that didn't work as I had hoped for.
Hmm. While there is a comment by Richard further down in the file:
// In fact write-only but there's no property
// for that.
it seems this may no longer be true. Looking at Intrinsics.td, I now see:
// IntrWriteMem - This intrinsic only writes to memory, but does not read from
// memory, and has no other side effects. This means dead stores before calls
// to this intrinsics may be removed.
def IntrWriteMem : IntrinsicProperty;
> \* Similarly,
>
> � def int\_s390\_ntstg : Intrinsic<\[\], \[llvm\_i64\_ty, llvm\_ptr64\_ty\],
> �������������������������������� \[IntrArgMemOnly\]>;
>
> does not load, but the using instruction must have the mayLoad flag set.
> Again, WriteOnly<1> does not work.
>
> \* This intrinsic:
>
> � def int\_s390\_tabort : Intrinsic<\[\], \[llvm\_i64\_ty\],
> ��������������������������������� \[IntrNoReturn, Throws\]>;
>
> should have just the hasSideEffects=1 on the instruction, but per the
> above intrinsic definition, both mayLoad and mayStore flags are required
> on the MI.
What about using IntrNoMem plus IntrHasSideEffects ?
> \* These two set/read the FP control register, and both have
> reg-reg/mem-reg variants. So EFPC and SFPC actually do not touch memory
> at all:
>
> � def int\_s390\_sfpc : GCCBuiltin<"\_\_builtin\_s390\_sfpc">,
> ��������������������� Intrinsic<\[\], \[llvm\_i32\_ty\], \[\]>;
> � def int\_s390\_efpc : GCCBuiltin<"\_\_builtin\_s390\_efpc">,
> ��������������������� Intrinsic<\[llvm\_i32\_ty\], \[\], \[\]>;
>
> � let mayLoad = 1, mayStore = 1 in {
> ��� def EFPC� : InherentRRE<"efpc", 0xB38C, GR32,
> int\_s390\_efpc>;���������� // no-mem
> ��� def STFPC : StoreInherentS<"stfpc", 0xB29C, storei,
> 4>;� // stores
>
> �� def SFPC : SideEffectUnaryRRE<"sfpc", 0xB384, GR32,
> int\_s390\_sfpc>;����� // no-mem
> �� def LFPC : SideEffectUnaryS<"lfpc", 0xB29D, loadu,
> 4>;>;� // loads
> }
>
> Is the proper solution in this case to make a duplicate version for each
> intrinsic that does not touch memory?
I'd just use IntrNoMem here. The variants that match the mem-reg cases
will have both the intrinsic and a load/store node in the DAG, and will
inherit the mayLoad / mayStore property from the latter node.
Bye,
Ulrich