[llvm-dev] SystemZ intrinsics definitions / memory flags

Ulrich Weigand via llvm-dev llvm-dev at lists.llvm.org
Thu Nov 30 04:37:24 PST 2017


Jonas Paulsson <paulsson at linux.vnet.ibm.com> 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<int_s390_efpc>,
> 4>;  // stores
>
>     def SFPC : SideEffectUnaryRRE<"sfpc", 0xB384, GR32,
> int_s390_sfpc>;      // no-mem
>     def LFPC : SideEffectUnaryS<"lfpc", 0xB29D, loadu<int_s390_sfpc>,
> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171130/3f0fc4d8/attachment.html>


More information about the llvm-dev mailing list