[llvm-dev] SystemZ intrinsics definitions / memory flags

Jonas Paulsson via llvm-dev llvm-dev at lists.llvm.org
Thu Nov 30 03:11:56 PST 2017


Hi,

I would like some help on how to change some SystemZ intrinsics (memory) 
flags that are wrong. Currently MIs are forced to have known wrong flags 
because they have an intrinsic in their pattern that demands the 
instruction to also have the same flag. The problem is that I couldn't 
figure out how to change the intrinsic flags...

* 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.

* 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.

* 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?

Any suggestions welcome,

/Jonas



More information about the llvm-dev mailing list