[llvm] r319756 - [SystemZ] set 'guessInstructionProperties = 0' and set flags as needed.

Jonas Paulsson via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 5 03:24:39 PST 2017


Author: jonpa
Date: Tue Dec  5 03:24:39 2017
New Revision: 319756

URL: http://llvm.org/viewvc/llvm-project?rev=319756&view=rev
Log:
[SystemZ]  set 'guessInstructionProperties = 0' and set flags as needed.

This has proven a healthy exercise, as many cases of incorrect instruction
flags were corrected in the process. As part of this, IntrWriteMem was added
to several SystemZ instrinsics.

Furthermore, a bug was exposed in TwoAddress with this change (as incorrect
hasSideEffects flags were removed and instructions could now be sunk), and
the test case for that bugfix (r319646) is included here as
test/CodeGen/SystemZ/twoaddr-sink.ll.

One temporary test regression (one extra copy) which will hopefully go away
in upcoming patches for similar cases:
test/CodeGen/SystemZ/vec-trunc-to-i1.ll

Review: Ulrich Weigand.
https://reviews.llvm.org/D40437

Added:
    llvm/trunk/test/CodeGen/SystemZ/twoaddr-sink.ll
Modified:
    llvm/trunk/include/llvm/IR/IntrinsicsSystemZ.td
    llvm/trunk/lib/Target/SystemZ/SystemZ.td
    llvm/trunk/lib/Target/SystemZ/SystemZInstrFP.td
    llvm/trunk/lib/Target/SystemZ/SystemZInstrFormats.td
    llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
    llvm/trunk/lib/Target/SystemZ/SystemZInstrSystem.td
    llvm/trunk/lib/Target/SystemZ/SystemZInstrVector.td
    llvm/trunk/test/CodeGen/SystemZ/backchain.ll
    llvm/trunk/test/CodeGen/SystemZ/risbg-01.ll
    llvm/trunk/test/CodeGen/SystemZ/vec-trunc-to-i1.ll

Modified: llvm/trunk/include/llvm/IR/IntrinsicsSystemZ.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicsSystemZ.td?rev=319756&r1=319755&r2=319756&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/IntrinsicsSystemZ.td (original)
+++ llvm/trunk/include/llvm/IR/IntrinsicsSystemZ.td Tue Dec  5 03:24:39 2017
@@ -198,14 +198,14 @@ multiclass SystemZQuaternaryIntCCBHF {
 
 let TargetPrefix = "s390" in {
   def int_s390_tbegin : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty],
-                                  [IntrNoDuplicate]>;
+                                  [IntrNoDuplicate, IntrWriteMem]>;
 
   def int_s390_tbegin_nofloat : Intrinsic<[llvm_i32_ty],
                                           [llvm_ptr_ty, llvm_i32_ty],
-                                          [IntrNoDuplicate]>;
+                                          [IntrNoDuplicate, IntrWriteMem]>;
 
   def int_s390_tbeginc : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty],
-                                   [IntrNoDuplicate]>;
+                                   [IntrNoDuplicate, IntrWriteMem]>;
 
   def int_s390_tabort : Intrinsic<[], [llvm_i64_ty],
                                   [IntrNoReturn, Throws]>;
@@ -217,7 +217,7 @@ let TargetPrefix = "s390" in {
                       Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
 
   def int_s390_ntstg : Intrinsic<[], [llvm_i64_ty, llvm_ptr64_ty],
-                                 [IntrArgMemOnly]>;
+                                 [IntrArgMemOnly, IntrWriteMem]>;
 
   def int_s390_ppa_txassist : GCCBuiltin<"__builtin_tx_assist">,
                               Intrinsic<[], [llvm_i32_ty]>;
@@ -260,9 +260,7 @@ let TargetPrefix = "s390" in {
 
   def int_s390_vstl : GCCBuiltin<"__builtin_s390_vstl">,
                       Intrinsic<[], [llvm_v16i8_ty, llvm_i32_ty, llvm_ptr_ty],
-                                // In fact write-only but there's no property
-                                // for that.
-                                [IntrArgMemOnly]>;
+                                [IntrArgMemOnly, IntrWriteMem]>;
 
   defm int_s390_vupl  : SystemZUnaryExtBHWF<"vupl">;
   defm int_s390_vupll : SystemZUnaryExtBHF<"vupll">;
@@ -413,9 +411,7 @@ let TargetPrefix = "s390" in {
 
   def int_s390_vstrl : GCCBuiltin<"__builtin_s390_vstrl">,
                        Intrinsic<[], [llvm_v16i8_ty, llvm_i32_ty, llvm_ptr_ty],
-                                 // In fact write-only but there's no property
-                                 // for that.
-                                 [IntrArgMemOnly]>;
+                                 [IntrArgMemOnly, IntrWriteMem]>;
 }
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/SystemZ/SystemZ.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZ.td?rev=319756&r1=319755&r2=319756&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZ.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZ.td Tue Dec  5 03:24:39 2017
@@ -58,7 +58,7 @@ include "SystemZInstrHFP.td"
 include "SystemZInstrDFP.td"
 include "SystemZInstrSystem.td"
 
-def SystemZInstrInfo : InstrInfo {}
+def SystemZInstrInfo : InstrInfo { let guessInstructionProperties = 0; }
 
 //===----------------------------------------------------------------------===//
 // Assembly parser

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrFP.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrFP.td?rev=319756&r1=319755&r2=319756&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrFP.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrFP.td Tue Dec  5 03:24:39 2017
@@ -7,6 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+// TODO: Most floating-point instructions (except for simple moves and the
+// like) can raise exceptions -- should they have hasSideEffects=1 ?
+
 //===----------------------------------------------------------------------===//
 // Select instructions
 //===----------------------------------------------------------------------===//
@@ -29,22 +32,20 @@ defm CondStoreF64 : CondStores<FP64, non
 //===----------------------------------------------------------------------===//
 
 // Load zero.
-let hasSideEffects = 0, isAsCheapAsAMove = 1, isMoveImm = 1 in {
+let isAsCheapAsAMove = 1, isMoveImm = 1 in {
   def LZER : InherentRRE<"lzer", 0xB374, FP32,  fpimm0>;
   def LZDR : InherentRRE<"lzdr", 0xB375, FP64,  fpimm0>;
   def LZXR : InherentRRE<"lzxr", 0xB376, FP128, fpimm0>;
 }
 
 // Moves between two floating-point registers.
-let hasSideEffects = 0 in {
-  def LER : UnaryRR <"ler", 0x38,   null_frag, FP32,  FP32>;
-  def LDR : UnaryRR <"ldr", 0x28,   null_frag, FP64,  FP64>;
-  def LXR : UnaryRRE<"lxr", 0xB365, null_frag, FP128, FP128>;
+def LER : UnaryRR <"ler", 0x38,   null_frag, FP32,  FP32>;
+def LDR : UnaryRR <"ldr", 0x28,   null_frag, FP64,  FP64>;
+def LXR : UnaryRRE<"lxr", 0xB365, null_frag, FP128, FP128>;
 
-  // For z13 we prefer LDR over LER to avoid partial register dependencies.
-  let isCodeGenOnly = 1 in
-    def LDR32 : UnaryRR<"ldr", 0x28, null_frag, FP32, FP32>;
-}
+// For z13 we prefer LDR over LER to avoid partial register dependencies.
+let isCodeGenOnly = 1 in
+  def LDR32 : UnaryRR<"ldr", 0x28, null_frag, FP32, FP32>;
 
 // Moves between two floating-point registers that also set the condition
 // codes.
@@ -130,7 +131,7 @@ defm LoadStoreF128 : MVCLoadStore<load,
 // Load instructions
 //===----------------------------------------------------------------------===//
 
-let canFoldAsLoad = 1, SimpleBDXLoad = 1 in {
+let canFoldAsLoad = 1, SimpleBDXLoad = 1, mayLoad = 1 in {
   defm LE : UnaryRXPair<"le", 0x78, 0xED64, load, FP32, 4>;
   defm LD : UnaryRXPair<"ld", 0x68, 0xED65, load, FP64, 8>;
 
@@ -150,7 +151,7 @@ let canFoldAsLoad = 1, SimpleBDXLoad = 1
 // Store instructions
 //===----------------------------------------------------------------------===//
 
-let SimpleBDXStore = 1 in {
+let SimpleBDXStore = 1, mayStore = 1 in {
   defm STE : StoreRXPair<"ste", 0x70, 0xED66, store, FP32, 4>;
   defm STD : StoreRXPair<"std", 0x60, 0xED67, store, FP64, 8>;
 
@@ -525,11 +526,14 @@ let Defs = [CC], CCValues = 0xC in {
 //===----------------------------------------------------------------------===//
 
 let hasSideEffects = 1 in {
-  def EFPC  : InherentRRE<"efpc", 0xB38C, GR32, int_s390_efpc>;
-  def STFPC : StoreInherentS<"stfpc", 0xB29C, storei<int_s390_efpc>, 4>;
+  let mayLoad = 1, mayStore = 1 in {
+    // TODO: EFPC and SFPC do not touch memory at all
+    def EFPC  : InherentRRE<"efpc", 0xB38C, GR32, int_s390_efpc>;
+    def STFPC : StoreInherentS<"stfpc", 0xB29C, storei<int_s390_efpc>, 4>;
 
-  def SFPC : SideEffectUnaryRRE<"sfpc", 0xB384, GR32, int_s390_sfpc>;
-  def LFPC : SideEffectUnaryS<"lfpc", 0xB29D, loadu<int_s390_sfpc>, 4>;
+    def SFPC : SideEffectUnaryRRE<"sfpc", 0xB384, GR32, int_s390_sfpc>;
+    def LFPC : SideEffectUnaryS<"lfpc", 0xB29D, loadu<int_s390_sfpc>, 4>;
+  }
 
   def SFASR : SideEffectUnaryRRE<"sfasr", 0xB385, GR32, null_frag>;
   def LFAS  : SideEffectUnaryS<"lfas", 0xB2BD, null_frag, 4>;

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrFormats.td?rev=319756&r1=319755&r2=319756&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrFormats.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrFormats.td Tue Dec  5 03:24:39 2017
@@ -21,6 +21,10 @@ class InstSystemZ<int size, dag outs, da
   let Pattern = pattern;
   let AsmString = asmstr;
 
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 0;
+
   // Some instructions come in pairs, one having a 12-bit displacement
   // and the other having a 20-bit displacement.  Both instructions in
   // the pair have the same DispKey and their DispSizes are "12" and "20"
@@ -2100,11 +2104,14 @@ class CondBranchRXY<string mnemonic, bit
   : InstRXYb<opcode, (outs), (ins cond4:$valid, cond4:$M1, bdxaddr20only:$XBD2),
              !subst("#", "${M1}", mnemonic)#"\t$XBD2", []> {
   let CCMaskFirst = 1;
+  let mayLoad = 1;
 }
 
 class AsmCondBranchRXY<string mnemonic, bits<16> opcode>
   : InstRXYb<opcode, (outs), (ins imm32zx4:$M1, bdxaddr20only:$XBD2),
-             mnemonic#"\t$M1, $XBD2", []>;
+             mnemonic#"\t$M1, $XBD2", []> {
+  let mayLoad = 1;
+}
 
 class FixedCondBranchRXY<CondVariant V, string mnemonic, bits<16> opcode,
                          SDPatternOperator operator = null_frag>
@@ -2113,6 +2120,7 @@ class FixedCondBranchRXY<CondVariant V,
              [(operator (load bdxaddr20only:$XBD2))]> {
   let isAsmParserOnly = V.alternate;
   let M1 = V.ccmask;
+  let mayLoad = 1;
 }
 
 class CmpBranchRIEa<string mnemonic, bits<16> opcode,
@@ -2784,7 +2792,6 @@ multiclass CondUnaryRSYPair<string mnemo
   def Asm : AsmCondUnaryRSY<mnemonic, opcode, cls, bytes, mode>;
 }
 
-
 class UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
               RegisterOperand cls, bits<5> bytes,
               AddressingMode mode = bdxaddr12only>
@@ -4688,7 +4695,8 @@ class SelectWrapper<ValueType vt, Regist
 // Stores $new to $addr if $cc is true ("" case) or false (Inv case).
 multiclass CondStores<RegisterOperand cls, SDPatternOperator store,
                       SDPatternOperator load, AddressingMode mode> {
-  let Defs = [CC], Uses = [CC], usesCustomInserter = 1 in {
+  let Defs = [CC], Uses = [CC], usesCustomInserter = 1,
+      mayLoad = 1, mayStore = 1 in {
     def "" : Pseudo<(outs),
                     (ins cls:$new, mode:$addr, imm32zx4:$valid, imm32zx4:$cc),
                     [(store (z_select_ccmask cls:$new, (load mode:$addr),

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td?rev=319756&r1=319755&r2=319756&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td Tue Dec  5 03:24:39 2017
@@ -11,24 +11,25 @@
 // Stack allocation
 //===----------------------------------------------------------------------===//
 
-let hasNoSchedulingInfo = 1 in {
+// The callseq_start node requires the hasSideEffects flag, even though these
+// instructions are noops on SystemZ.
+let hasNoSchedulingInfo = 1, hasSideEffects = 1 in {
   def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
                                 [(callseq_start timm:$amt1, timm:$amt2)]>;
   def ADJCALLSTACKUP   : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
                                 [(callseq_end timm:$amt1, timm:$amt2)]>;
 }
 
-let hasSideEffects = 0 in {
-  // Takes as input the value of the stack pointer after a dynamic allocation
-  // has been made.  Sets the output to the address of the dynamically-
-  // allocated area itself, skipping the outgoing arguments.
-  //
-  // This expands to an LA or LAY instruction.  We restrict the offset
-  // to the range of LA and keep the LAY range in reserve for when
-  // the size of the outgoing arguments is added.
-  def ADJDYNALLOC : Pseudo<(outs GR64:$dst), (ins dynalloc12only:$src),
-                           [(set GR64:$dst, dynalloc12only:$src)]>;
-}
+// Takes as input the value of the stack pointer after a dynamic allocation
+// has been made.  Sets the output to the address of the dynamically-
+// allocated area itself, skipping the outgoing arguments.
+//
+// This expands to an LA or LAY instruction.  We restrict the offset
+// to the range of LA and keep the LAY range in reserve for when
+// the size of the outgoing arguments is added.
+def ADJDYNALLOC : Pseudo<(outs GR64:$dst), (ins dynalloc12only:$src),
+                         [(set GR64:$dst, dynalloc12only:$src)]>;
+
 
 //===----------------------------------------------------------------------===//
 // Branch instructions
@@ -197,15 +198,15 @@ let isBranch = 1, isTerminator = 1 in {
 //===----------------------------------------------------------------------===//
 
 // Unconditional trap.
-let hasCtrlDep = 1 in
+let hasCtrlDep = 1, hasSideEffects = 1 in
   def Trap : Alias<4, (outs), (ins), [(trap)]>;
 
 // Conditional trap.
-let hasCtrlDep = 1, Uses = [CC] in
+let hasCtrlDep = 1, Uses = [CC], hasSideEffects = 1 in
   def CondTrap : Alias<4, (outs), (ins cond4:$valid, cond4:$R1), []>;
 
 // Fused compare-and-trap instructions.
-let hasCtrlDep = 1 in {
+let hasCtrlDep = 1, hasSideEffects = 1 in {
   // These patterns work the same way as for compare-and-branch.
   defm CRT   : CmpBranchRRFcPair<"crt",   0xB972, GR32>;
   defm CGRT  : CmpBranchRRFcPair<"cgrt",  0xB960, GR64>;
@@ -360,13 +361,12 @@ defm CondStore64 : CondStores<GR64, nonv
 //===----------------------------------------------------------------------===//
 
 // Register moves.
-let hasSideEffects = 0 in {
-  // Expands to LR, RISBHG or RISBLG, depending on the choice of registers.
-  def LRMux : UnaryRRPseudo<"lr", null_frag, GRX32, GRX32>,
-              Requires<[FeatureHighWord]>;
-  def LR  : UnaryRR <"lr",  0x18,   null_frag, GR32, GR32>;
-  def LGR : UnaryRRE<"lgr", 0xB904, null_frag, GR64, GR64>;
-}
+// Expands to LR, RISBHG or RISBLG, depending on the choice of registers.
+def LRMux : UnaryRRPseudo<"lr", null_frag, GRX32, GRX32>,
+            Requires<[FeatureHighWord]>;
+def LR  : UnaryRR <"lr",  0x18,   null_frag, GR32, GR32>;
+def LGR : UnaryRRE<"lgr", 0xB904, null_frag, GR64, GR64>;
+
 let Defs = [CC], CCValues = 0xE, CompareZeroCCMask = 0xE in {
   def LTR  : UnaryRR <"ltr",  0x12,   null_frag, GR32, GR32>;
   def LTGR : UnaryRRE<"ltgr", 0xB902, null_frag, GR64, GR64>;
@@ -376,8 +376,7 @@ let usesCustomInserter = 1, hasNoSchedul
   def PAIR128 : Pseudo<(outs GR128:$dst), (ins GR64:$hi, GR64:$lo), []>;
 
 // Immediate moves.
-let hasSideEffects = 0, isAsCheapAsAMove = 1, isMoveImm = 1,
-    isReMaterializable = 1 in {
+let isAsCheapAsAMove = 1, isMoveImm = 1, isReMaterializable = 1 in {
   // 16-bit sign-extended immediates.  LHIMux expands to LHI or IIHF,
   // deopending on the choice of register.
   def LHIMux : UnaryRIPseudo<bitconvert, GRX32, imm32sx16>,
@@ -398,7 +397,7 @@ let hasSideEffects = 0, isAsCheapAsAMove
 }
 
 // Register loads.
-let canFoldAsLoad = 1, SimpleBDXLoad = 1 in {
+let canFoldAsLoad = 1, SimpleBDXLoad = 1, mayLoad = 1 in {
   // Expands to L, LY or LFH, depending on the choice of register.
   def LMux : UnaryRXYPseudo<"l", load, GRX32, 4>,
              Requires<[FeatureHighWord]>;
@@ -435,14 +434,14 @@ let Predicates = [FeatureLoadAndZeroRigh
 }
 
 // Load and trap.
-let Predicates = [FeatureLoadAndTrap] in {
+let Predicates = [FeatureLoadAndTrap], hasSideEffects = 1 in {
   def LAT   : UnaryRXY<"lat",   0xE39F, null_frag, GR32, 4>;
   def LFHAT : UnaryRXY<"lfhat", 0xE3C8, null_frag, GRH32, 4>;
   def LGAT  : UnaryRXY<"lgat",  0xE385, null_frag, GR64, 8>;
 }
 
 // Register stores.
-let SimpleBDXStore = 1 in {
+let SimpleBDXStore = 1, mayStore = 1 in {
   // Expands to ST, STY or STFH, depending on the choice of register.
   def STMux : StoreRXYPseudo<store, GRX32, 4>,
               Requires<[FeatureHighWord]>;
@@ -489,17 +488,16 @@ let mayLoad = 1, mayStore = 1, Defs = [C
 let Predicates = [FeatureLoadStoreOnCond2], Uses = [CC] in {
   // Load immediate on condition.  Matched via DAG pattern and created
   // by the PeepholeOptimizer via FoldImmediate.
-  let hasSideEffects = 0 in {
-    // Expands to LOCHI or LOCHHI, depending on the choice of register.
-    def LOCHIMux : CondBinaryRIEPseudo<GRX32, imm32sx16>;
-    defm LOCHHI  : CondBinaryRIEPair<"lochhi", 0xEC4E, GRH32, imm32sx16>;
-    defm LOCHI   : CondBinaryRIEPair<"lochi",  0xEC42, GR32, imm32sx16>;
-    defm LOCGHI  : CondBinaryRIEPair<"locghi", 0xEC46, GR64, imm64sx16>;
-  }
+
+  // Expands to LOCHI or LOCHHI, depending on the choice of register.
+  def LOCHIMux : CondBinaryRIEPseudo<GRX32, imm32sx16>;
+  defm LOCHHI  : CondBinaryRIEPair<"lochhi", 0xEC4E, GRH32, imm32sx16>;
+  defm LOCHI   : CondBinaryRIEPair<"lochi",  0xEC42, GR32, imm32sx16>;
+  defm LOCGHI  : CondBinaryRIEPair<"locghi", 0xEC46, GR64, imm64sx16>;
 
   // Move register on condition.  Expanded from Select* pseudos and
   // created by early if-conversion.
-  let hasSideEffects = 0, isCommutable = 1 in {
+  let isCommutable = 1 in {
     // Expands to LOCR or LOCFHR or a branch-and-move sequence,
     // depending on the choice of registers.
     def LOCRMux : CondBinaryRRFPseudo<GRX32, GRX32>;
@@ -534,7 +532,7 @@ let Predicates = [FeatureLoadStoreOnCond
 let Predicates = [FeatureLoadStoreOnCond], Uses = [CC] in {
   // Move register on condition.  Expanded from Select* pseudos and
   // created by early if-conversion.
-  let hasSideEffects = 0, isCommutable = 1 in {
+  let isCommutable = 1 in {
     defm LOCR  : CondBinaryRRFPair<"locr",  0xB9F2, GR32, GR32>;
     defm LOCGR : CondBinaryRRFPair<"locgr", 0xB9E2, GR64, GR64>;
   }
@@ -570,17 +568,14 @@ let Predicates = [FeatureLoadStoreOnCond
 //===----------------------------------------------------------------------===//
 
 // 32-bit extensions from registers.
-let hasSideEffects = 0 in {
-  def LBR : UnaryRRE<"lbr", 0xB926, sext8,  GR32, GR32>;
-  def LHR : UnaryRRE<"lhr", 0xB927, sext16, GR32, GR32>;
-}
+def LBR : UnaryRRE<"lbr", 0xB926, sext8,  GR32, GR32>;
+def LHR : UnaryRRE<"lhr", 0xB927, sext16, GR32, GR32>;
 
 // 64-bit extensions from registers.
-let hasSideEffects = 0 in {
-  def LGBR : UnaryRRE<"lgbr", 0xB906, sext8,  GR64, GR64>;
-  def LGHR : UnaryRRE<"lghr", 0xB907, sext16, GR64, GR64>;
-  def LGFR : UnaryRRE<"lgfr", 0xB914, sext32, GR64, GR32>;
-}
+def LGBR : UnaryRRE<"lgbr", 0xB906, sext8,  GR64, GR64>;
+def LGHR : UnaryRRE<"lghr", 0xB907, sext16, GR64, GR64>;
+def LGFR : UnaryRRE<"lgfr", 0xB914, sext32, GR64, GR32>;
+
 let Defs = [CC], CCValues = 0xE, CompareZeroCCMask = 0xE in
   def LTGFR : UnaryRRE<"ltgfr", 0xB912, null_frag, GR64, GR32>;
 
@@ -620,23 +615,20 @@ let Defs = [CC], CCValues = 0xE, Compare
 //===----------------------------------------------------------------------===//
 
 // 32-bit extensions from registers.
-let hasSideEffects = 0 in {
-  // Expands to LLCR or RISB[LH]G, depending on the choice of registers.
-  def LLCRMux : UnaryRRPseudo<"llcr", zext8, GRX32, GRX32>,
-                Requires<[FeatureHighWord]>;
-  def LLCR    : UnaryRRE<"llcr", 0xB994, zext8,  GR32, GR32>;
-  // Expands to LLHR or RISB[LH]G, depending on the choice of registers.
-  def LLHRMux : UnaryRRPseudo<"llhr", zext16, GRX32, GRX32>,
-                Requires<[FeatureHighWord]>;
-  def LLHR    : UnaryRRE<"llhr", 0xB995, zext16, GR32, GR32>;
-}
+
+// Expands to LLCR or RISB[LH]G, depending on the choice of registers.
+def LLCRMux : UnaryRRPseudo<"llcr", zext8, GRX32, GRX32>,
+              Requires<[FeatureHighWord]>;
+def LLCR    : UnaryRRE<"llcr", 0xB994, zext8,  GR32, GR32>;
+// Expands to LLHR or RISB[LH]G, depending on the choice of registers.
+def LLHRMux : UnaryRRPseudo<"llhr", zext16, GRX32, GRX32>,
+              Requires<[FeatureHighWord]>;
+def LLHR    : UnaryRRE<"llhr", 0xB995, zext16, GR32, GR32>;
 
 // 64-bit extensions from registers.
-let hasSideEffects = 0 in {
-  def LLGCR : UnaryRRE<"llgcr", 0xB984, zext8,  GR64, GR64>;
-  def LLGHR : UnaryRRE<"llghr", 0xB985, zext16, GR64, GR64>;
-  def LLGFR : UnaryRRE<"llgfr", 0xB916, zext32, GR64, GR32>;
-}
+def LLGCR : UnaryRRE<"llgcr", 0xB984, zext8,  GR64, GR64>;
+def LLGHR : UnaryRRE<"llghr", 0xB985, zext16, GR64, GR64>;
+def LLGFR : UnaryRRE<"llgfr", 0xB916, zext32, GR64, GR32>;
 
 // Match 32-to-64-bit zero extensions in which the source is already
 // in a 64-bit register.
@@ -683,7 +675,7 @@ let Predicates = [FeatureLoadAndZeroRigh
 }
 
 // Load and trap.
-let Predicates = [FeatureLoadAndTrap] in {
+let Predicates = [FeatureLoadAndTrap], hasSideEffects = 1 in {
   def LLGFAT : UnaryRXY<"llgfat", 0xE39D, null_frag, GR64, 4>;
   def LLGTAT : UnaryRXY<"llgtat", 0xE39C, null_frag, GR64, 4>;
 }
@@ -760,10 +752,8 @@ def STMH : StoreMultipleRSY<"stmh", 0xEB
 //===----------------------------------------------------------------------===//
 
 // Byte-swapping register moves.
-let hasSideEffects = 0 in {
-  def LRVR  : UnaryRRE<"lrvr",  0xB91F, bswap, GR32, GR32>;
-  def LRVGR : UnaryRRE<"lrvgr", 0xB90F, bswap, GR64, GR64>;
-}
+def LRVR  : UnaryRRE<"lrvr",  0xB91F, bswap, GR32, GR32>;
+def LRVGR : UnaryRRE<"lrvgr", 0xB90F, bswap, GR64, GR64>;
 
 // Byte-swapping loads.  Unlike normal loads, these instructions are
 // allowed to access storage more than once.
@@ -785,13 +775,12 @@ let mayLoad = 1, mayStore = 1 in
 //===----------------------------------------------------------------------===//
 
 // Load BDX-style addresses.
-let hasSideEffects = 0, isAsCheapAsAMove = 1, isReMaterializable = 1 in
+let isAsCheapAsAMove = 1, isReMaterializable = 1 in
   defm LA : LoadAddressRXPair<"la", 0x41, 0xE371, bitconvert>;
 
 // Load a PC-relative address.  There's no version of this instruction
 // with a 16-bit offset, so there's no relaxation.
-let hasSideEffects = 0, isAsCheapAsAMove = 1, isMoveImm = 1,
-    isReMaterializable = 1 in
+let isAsCheapAsAMove = 1, isMoveImm = 1, isReMaterializable = 1 in
   def LARL : LoadAddressRIL<"larl", 0xC00, bitconvert>;
 
 // Load the Global Offset Table address.  This will be lowered into a
@@ -1267,6 +1256,7 @@ def MGRK : BinaryRRFa<"mgrk", 0xB9EC, nu
            Requires<[FeatureMiscellaneousExtensions2]>;
 def MLR  : BinaryRRE<"mlr",  0xB996, null_frag, GR128, GR32>;
 def MLGR : BinaryRRE<"mlgr", 0xB986, null_frag, GR128, GR64>;
+
 def : Pat<(z_smul_lohi GR64:$src1, GR64:$src2),
           (MGRK GR64:$src1, GR64:$src2)>;
 def : Pat<(z_umul_lohi GR64:$src1, GR64:$src2),
@@ -1279,6 +1269,7 @@ def MG  : BinaryRXY<"mg",  0xE384, null_
           Requires<[FeatureMiscellaneousExtensions2]>;
 def ML  : BinaryRXY<"ml",  0xE396, null_frag, GR128, load, 4>;
 def MLG : BinaryRXY<"mlg", 0xE386, null_frag, GR128, load, 8>;
+
 def : Pat<(z_smul_lohi GR64:$src1, (i64 (load bdxaddr20only:$src2))),
           (MG (AEXT128 GR64:$src1), bdxaddr20only:$src2)>;
 def : Pat<(z_umul_lohi GR64:$src1, (i64 (load bdxaddr20only:$src2))),
@@ -1328,11 +1319,9 @@ def : Pat<(z_udivrem GR64:$src1, (i64 (l
 //===----------------------------------------------------------------------===//
 
 // Logical shift left.
-let hasSideEffects = 0 in {
-  defm SLL : BinaryRSAndK<"sll", 0x89, 0xEBDF, shl, GR32>;
-  def SLLG : BinaryRSY<"sllg", 0xEB0D, shl, GR64>;
-  def SLDL : BinaryRS<"sldl", 0x8D, null_frag, GR128>;
-}
+defm SLL : BinaryRSAndK<"sll", 0x89, 0xEBDF, shl, GR32>;
+def SLLG : BinaryRSY<"sllg", 0xEB0D, shl, GR64>;
+def SLDL : BinaryRS<"sldl", 0x8D, null_frag, GR128>;
 
 // Arithmetic shift left.
 let Defs = [CC] in {
@@ -1342,11 +1331,9 @@ let Defs = [CC] in {
 }
 
 // Logical shift right.
-let hasSideEffects = 0 in {
-  defm SRL : BinaryRSAndK<"srl", 0x88, 0xEBDE, srl, GR32>;
-  def SRLG : BinaryRSY<"srlg", 0xEB0C, srl, GR64>;
-  def SRDL : BinaryRS<"srdl", 0x8C, null_frag, GR128>;
-}
+defm SRL : BinaryRSAndK<"srl", 0x88, 0xEBDE, srl, GR32>;
+def SRLG : BinaryRSY<"srlg", 0xEB0C, srl, GR64>;
+def SRDL : BinaryRS<"srdl", 0x8C, null_frag, GR128>;
 
 // Arithmetic shift right.
 let Defs = [CC], CCValues = 0xE, CompareZeroCCMask = 0xE in {
@@ -1356,10 +1343,8 @@ let Defs = [CC], CCValues = 0xE, Compare
 }
 
 // Rotate left.
-let hasSideEffects = 0 in {
-  def RLL  : BinaryRSY<"rll",  0xEB1D, rotl, GR32>;
-  def RLLG : BinaryRSY<"rllg", 0xEB1C, rotl, GR64>;
-}
+def RLL  : BinaryRSY<"rll",  0xEB1D, rotl, GR32>;
+def RLLG : BinaryRSY<"rllg", 0xEB1C, rotl, GR64>;
 
 // Rotate second operand left and inserted selected bits into first operand.
 // These can act like 32-bit operands provided that the constant start and
@@ -1550,10 +1535,12 @@ let Defs = [CC] in {
 // Prefetch and execution hint
 //===----------------------------------------------------------------------===//
 
-def PFD : PrefetchRXY<"pfd", 0xE336, z_prefetch>;
-def PFDRL : PrefetchRILPC<"pfdrl", 0xC62, z_prefetch>;
+let mayLoad = 1, mayStore = 1 in {
+  def PFD : PrefetchRXY<"pfd", 0xE336, z_prefetch>;
+  def PFDRL : PrefetchRILPC<"pfdrl", 0xC62, z_prefetch>;
+}
 
-let Predicates = [FeatureExecutionHint] in {
+let Predicates = [FeatureExecutionHint], hasSideEffects = 1 in {
   // Branch Prediction Preload
   def BPP : BranchPreloadSMI<"bpp", 0xC7>;
   def BPRP : BranchPreloadMII<"bprp", 0xC5>;
@@ -1820,7 +1807,10 @@ let mayLoad = 1, mayStore = 1, Uses = [R
 // Guarded storage
 //===----------------------------------------------------------------------===//
 
-let Predicates = [FeatureGuardedStorage] in {
+// These instructions use and/or modify the guarded storage control
+// registers, which we do not otherwise model, so they should have
+// hasSideEffects.
+let Predicates = [FeatureGuardedStorage], hasSideEffects = 1 in {
   def LGG : UnaryRXY<"lgg", 0xE34C, null_frag, GR64, 8>;
   def LLGFSG : UnaryRXY<"llgfsg", 0xE348, null_frag, GR64, 4>;
 
@@ -1896,7 +1886,7 @@ defm LAE : LoadAddressRXPair<"lae", 0x51
 // Load access multiple.
 defm LAM : LoadMultipleRSPair<"lam", 0x9A, 0xEB9A, AR32>;
 
-// Load access multiple.
+// Store access multiple.
 defm STAM : StoreMultipleRSPair<"stam", 0x9B, 0xEB9B, AR32>;
 
 //===----------------------------------------------------------------------===//
@@ -1945,7 +1935,6 @@ let hasSideEffects = 1, Predicates = [Fe
   let mayStore = 1, usesCustomInserter = 1, Defs = [CC] in {
     def TBEGIN : SideEffectBinarySIL<"tbegin", 0xE560, z_tbegin, imm32zx16>;
     def TBEGIN_nofloat : SideEffectBinarySILPseudo<z_tbegin_nofloat, imm32zx16>;
-
     def TBEGINC : SideEffectBinarySIL<"tbeginc", 0xE561,
                                       int_s390_tbeginc, imm32zx16>;
   }
@@ -1955,7 +1944,9 @@ let hasSideEffects = 1, Predicates = [Fe
     def TEND : SideEffectInherentS<"tend", 0xB2F8, z_tend>;
 
   // Transaction Abort
-  let isTerminator = 1, isBarrier = 1 in
+  // TODO: Shouldn't be mayLoad or mayStore.
+  let isTerminator = 1, isBarrier = 1, mayLoad = 1, mayStore = 1,
+      hasSideEffects = 1 in
     def TABORT : SideEffectAddressS<"tabort", 0xB2FC, int_s390_tabort>;
 
   // Nontransactional Store
@@ -2031,7 +2022,7 @@ let hasSideEffects = 1 in {
 // .insn directive instructions
 //===----------------------------------------------------------------------===//
 
-let isCodeGenOnly = 1 in {
+let isCodeGenOnly = 1, hasSideEffects = 1 in {
   def InsnE   : DirectiveInsnE<(outs), (ins imm64zx16:$enc), ".insn e,$enc", []>;
   def InsnRI  : DirectiveInsnRI<(outs), (ins imm64zx32:$enc, AnyReg:$R1,
                                              imm32sx16:$I2),

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrSystem.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrSystem.td?rev=319756&r1=319755&r2=319756&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrSystem.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrSystem.td Tue Dec  5 03:24:39 2017
@@ -23,7 +23,7 @@ let hasSideEffects = 1, Uses = [CC] in
   def EPSW : InherentDualRRE<"epsw", 0xB98D, GR32>;
 
 // Load PSW (extended).
-let hasSideEffects = 1, Defs = [CC], mayLoad = 1 in {
+let hasSideEffects = 1, Defs = [CC] in {
   def LPSW : SideEffectUnaryS<"lpsw", 0x8200, null_frag, 8>;
   def LPSWE : SideEffectUnaryS<"lpswe", 0xB2B2, null_frag, 16>;
 }
@@ -37,7 +37,7 @@ let hasSideEffects = 1 in
   def SPKA : SideEffectAddressS<"spka", 0xB20A, null_frag>;
 
 // Set system mask.
-let hasSideEffects = 1, mayLoad = 1 in
+let hasSideEffects = 1 in
   def SSM : SideEffectUnaryS<"ssm", 0x8000, null_frag, 1>;
 
 // Store then AND/OR system mask.
@@ -60,13 +60,15 @@ let hasSideEffects = 1 in {
 // Control Register Instructions.
 //===----------------------------------------------------------------------===//
 
-// Load control.
-def LCTL : LoadMultipleRS<"lctl", 0xB7, CR64>;
-def LCTLG : LoadMultipleRSY<"lctlg", 0xEB2F, CR64>;
-
-// Store control.
-def STCTL : StoreMultipleRS<"stctl", 0xB6, CR64>;
-def STCTG : StoreMultipleRSY<"stctg", 0xEB25, CR64>;
+let hasSideEffects = 1 in {
+  // Load control.
+  def LCTL : LoadMultipleRS<"lctl", 0xB7, CR64>;
+  def LCTLG : LoadMultipleRSY<"lctlg", 0xEB2F, CR64>;
+
+  // Store control.
+  def STCTL : StoreMultipleRS<"stctl", 0xB6, CR64>;
+  def STCTG : StoreMultipleRSY<"stctg", 0xEB25, CR64>;
+}
 
 // Extract primary ASN (and instance).
 let hasSideEffects = 1 in {

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrVector.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrVector.td?rev=319756&r1=319755&r2=319756&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrVector.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrVector.td Tue Dec  5 03:24:39 2017
@@ -56,8 +56,7 @@ def : VectorExtractSubreg<v4i32, VLGVF>;
 //===----------------------------------------------------------------------===//
 
 let Predicates = [FeatureVector] in {
-  let hasSideEffects = 0, isAsCheapAsAMove = 1, isMoveImm = 1,
-      isReMaterializable = 1 in {
+  let isAsCheapAsAMove = 1, isMoveImm = 1, isReMaterializable = 1 in {
 
     // Generate byte mask.
     def VZERO : InherentVRIa<"vzero", 0xE744, 0>;
@@ -141,8 +140,10 @@ let Predicates = [FeatureVector] in {
   // LEY and LDY offer full 20-bit displacement fields.  It's often better
   // to use those instructions rather than force a 20-bit displacement
   // into a GPR temporary.
-  def VL32 : UnaryAliasVRX<load, v32sb, bdxaddr12pair>;
-  def VL64 : UnaryAliasVRX<load, v64db, bdxaddr12pair>;
+  let mayLoad = 1 in {
+    def VL32 : UnaryAliasVRX<load, v32sb, bdxaddr12pair>;
+    def VL64 : UnaryAliasVRX<load, v64db, bdxaddr12pair>;
+  }
 
   // Load logical element and zero.
   def VLLEZ  : UnaryVRXGeneric<"vllez", 0xE704>;
@@ -231,8 +232,10 @@ let Predicates = [FeatureVector] in {
   // STEY and STDY offer full 20-bit displacement fields.  It's often better
   // to use those instructions rather than force a 20-bit displacement
   // into a GPR temporary.
-  def VST32 : StoreAliasVRX<store, v32sb, bdxaddr12pair>;
-  def VST64 : StoreAliasVRX<store, v64db, bdxaddr12pair>;
+  let mayStore = 1 in {
+    def VST32 : StoreAliasVRX<store, v32sb, bdxaddr12pair>;
+    def VST64 : StoreAliasVRX<store, v64db, bdxaddr12pair>;
+  }
 
   // Scatter element.
   def VSCEF : StoreBinaryVRV<"vscef", 0xE71B, 4, imm32zx2>;

Modified: llvm/trunk/test/CodeGen/SystemZ/backchain.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/backchain.ll?rev=319756&r1=319755&r2=319756&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/backchain.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/backchain.ll Tue Dec  5 03:24:39 2017
@@ -44,8 +44,8 @@ define void @f4(i32 %len) "backchain" {
 ; CHECK: aghi %r15, -160
 ; CHECK: stg %r1, 0(%r15)
 ; CHECK: lgr %r11, %r15
-; CHECK: lg [[BC:%r[0-9]+]], 0(%r15)
-; CHECK: lgr [[NEWSP:%r[0-9]+]], %r15
+; CHECK-DAG: lg [[BC:%r[0-9]+]], 0(%r15)
+; CHECK-DAG: lgr [[NEWSP:%r[0-9]+]], %r15
 ; CHECK: lgr %r15, [[NEWSP]]
 ; CHECK: stg [[BC]], 0([[NEWSP]])
   %ign = alloca i8, i32 %len

Modified: llvm/trunk/test/CodeGen/SystemZ/risbg-01.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/risbg-01.ll?rev=319756&r1=319755&r2=319756&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/risbg-01.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/risbg-01.ll Tue Dec  5 03:24:39 2017
@@ -233,9 +233,11 @@ define i64 @f20(i64 %foo) {
 ; Now try an arithmetic right shift in which the sign bits aren't needed.
 ; Introduce a second use of %shr so that the ashr doesn't decompose to
 ; an lshr.
+; NOTE: the extra move to %r2 should not be needed (temporary FAIL)
 define i32 @f21(i32 %foo, i32 *%dest) {
 ; CHECK-LABEL: f21:
-; CHECK: risbg %r2, %r2, 60, 190, 36
+; CHECK: risbg %r0, %r2, 60, 190, 36
+; CHECK: lr %r2, %r0
 ; CHECK: br %r14
   %shr = ashr i32 %foo, 28
   store i32 %shr, i32 *%dest

Added: llvm/trunk/test/CodeGen/SystemZ/twoaddr-sink.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/twoaddr-sink.ll?rev=319756&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/twoaddr-sink.ll (added)
+++ llvm/trunk/test/CodeGen/SystemZ/twoaddr-sink.ll Tue Dec  5 03:24:39 2017
@@ -0,0 +1,15 @@
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -no-integrated-as
+;
+; Check that TwoAddressInstructionPass does not crash after sinking (and
+; revisiting) an instruction that was lowered by TII->convertToThreeAddress()
+; which contains a %noreg operand.
+
+define i32 @f23(i32 %old) {
+  %and1 = and i32 %old, 14
+  %and2 = and i32 %old, 254
+  %res1 = call i32 asm "stepa $1, $2, $3", "=h,r,r,0"(i32 %old, i32 %and1, i32 %and2)
+  %and3 = and i32 %res1, 127
+  %and4 = and i32 %res1, 128
+  %res2 = call i32 asm "stepb $1, $2, $3", "=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4)
+  ret i32 %res2
+}

Modified: llvm/trunk/test/CodeGen/SystemZ/vec-trunc-to-i1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/vec-trunc-to-i1.ll?rev=319756&r1=319755&r2=319756&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/vec-trunc-to-i1.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/vec-trunc-to-i1.ll Tue Dec  5 03:24:39 2017
@@ -1,26 +1,23 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-;
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
 ;
 ; Check that a widening truncate to a vector of i1 elements can be handled.
 
-
+; NOTE: REG2 is actually not needed (tempororary FAIL)
 define void @pr32275(<4 x i8> %B15) {
 ; CHECK-LABEL: pr32275:
 ; CHECK:       # %bb.0: # %BB
-; CHECK-NEXT:    vrepif %v0, 1
-; CHECK-NEXT:  .LBB0_1: # %CF34
-; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vlgvb %r0, %v24, 3
+; CHECK-NEXT:    vrepif [[REG0:%v[0-9]]], 1
+; CHECK:         vlgvb %r0, %v24, 3
 ; CHECK-NEXT:    vlgvb %r1, %v24, 1
-; CHECK-NEXT:    vlvgp %v1, %r1, %r0
+; CHECK-NEXT:    vlvgp [[REG1:%v[0-9]]], %r1, %r0
 ; CHECK-NEXT:    vlgvb %r0, %v24, 0
-; CHECK-NEXT:    vlvgf %v1, %r0, 0
-; CHECK-NEXT:    vlgvb %r0, %v24, 2
-; CHECK-NEXT:    vlvgf %v1, %r0, 2
-; CHECK-NEXT:    vn %v1, %v1, %v0
-; CHECK-NEXT:    vlgvf %r0, %v1, 3
-; CHECK-NEXT:    tmll %r0, 1
+; CHECK-DAG:     vlr [[REG2:%v[0-9]]], [[REG1]]
+; CHECK-DAG:     vlvgf [[REG2]], %r0, 0
+; CHECK-DAG:     vlgvb [[REG3:%r[0-9]]], %v24, 2
+; CHECK-NEXT:    vlvgf [[REG2]], [[REG3]], 2
+; CHECK-NEXT:    vn [[REG2]], [[REG2]], [[REG0]]
+; CHECK-NEXT:    vlgvf [[REG4:%r[0-9]]], [[REG2]], 3
+; CHECK-NEXT:    tmll [[REG4]], 1
 ; CHECK-NEXT:    jne .LBB0_1
 ; CHECK-NEXT:  # %bb.2: # %CF36
 ; CHECK-NEXT:    br %r14




More information about the llvm-commits mailing list