[SystemZ] Postpone NI->RISBG conversion to convertToThreeAddress()
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Wed, 31 Jul 2013 11:36:35 +0000 (11:36 +0000)
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Wed, 31 Jul 2013 11:36:35 +0000 (11:36 +0000)
r186399 aggressively used the RISBG instruction for immediate ANDs,
both because it can handle some values that AND IMMEDIATE can't,
and because it allows the destination register to be different from
the source.  I realized later while implementing the distinct-ops
support that it would be better to leave the choice up to
convertToThreeAddress() instead.  The AND IMMEDIATE form is shorter
and is less likely to be cracked.

This is a problem for 32-bit ANDs because we assume that all 32-bit
operations will leave the high word untouched, whereas RISBG used in
this way will either clear the high word or copy it from the source
register.  The patch uses the z196 instruction RISBLG for this instead.

This means that z10 will be restricted to NILL, NILH and NILF for
32-bit ANDs, but I think that should be OK for now.  Although we're
using z10 as the base architecture, the optimization work is going
to be focused more on z196 and zEC12.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187492 91177308-0d34-0410-b5e6-96231b3b80d8

33 files changed:
lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
lib/Target/SystemZ/SystemZInstrInfo.cpp
lib/Target/SystemZ/SystemZInstrInfo.h
lib/Target/SystemZ/SystemZInstrInfo.td
test/CodeGen/SystemZ/addr-01.ll
test/CodeGen/SystemZ/addr-02.ll
test/CodeGen/SystemZ/alloca-01.ll
test/CodeGen/SystemZ/and-02.ll
test/CodeGen/SystemZ/and-04.ll
test/CodeGen/SystemZ/atomicrmw-add-01.ll
test/CodeGen/SystemZ/atomicrmw-add-02.ll
test/CodeGen/SystemZ/atomicrmw-and-01.ll
test/CodeGen/SystemZ/atomicrmw-and-02.ll
test/CodeGen/SystemZ/atomicrmw-and-04.ll
test/CodeGen/SystemZ/atomicrmw-minmax-01.ll
test/CodeGen/SystemZ/atomicrmw-minmax-02.ll
test/CodeGen/SystemZ/atomicrmw-nand-01.ll
test/CodeGen/SystemZ/atomicrmw-nand-02.ll
test/CodeGen/SystemZ/atomicrmw-nand-04.ll
test/CodeGen/SystemZ/atomicrmw-or-01.ll
test/CodeGen/SystemZ/atomicrmw-or-02.ll
test/CodeGen/SystemZ/atomicrmw-sub-01.ll
test/CodeGen/SystemZ/atomicrmw-sub-02.ll
test/CodeGen/SystemZ/atomicrmw-xchg-01.ll
test/CodeGen/SystemZ/atomicrmw-xchg-02.ll
test/CodeGen/SystemZ/atomicrmw-xor-01.ll
test/CodeGen/SystemZ/atomicrmw-xor-02.ll
test/CodeGen/SystemZ/cmpxchg-01.ll
test/CodeGen/SystemZ/cmpxchg-02.ll
test/CodeGen/SystemZ/fp-move-02.ll
test/CodeGen/SystemZ/insert-01.ll
test/CodeGen/SystemZ/insert-02.ll
test/CodeGen/SystemZ/risbg-01.ll

index 8866253484ea951c21d1a4ab4eee804c17b89662..b7e966ff011f7f4706c0490eaf59251a21ae495b 100644 (file)
@@ -132,6 +132,14 @@ class SystemZDAGToDAGISel : public SelectionDAGISel {
     return CurDAG->getTargetConstant(Imm, Node->getValueType(0));
   }
 
+  const SystemZTargetMachine &getTargetMachine() const {
+    return static_cast<const SystemZTargetMachine &>(TM);
+  }
+
+  const SystemZInstrInfo *getInstrInfo() const {
+    return getTargetMachine().getInstrInfo();
+  }
+
   // Try to fold more of the base or index of AM into AM, where IsBase
   // selects between the base and index.
   bool expandAddress(SystemZAddressingMode &AM, bool IsBase);
@@ -236,6 +244,10 @@ class SystemZDAGToDAGISel : public SelectionDAGISel {
   // set Op to that Y.
   bool detectOrAndInsertion(SDValue &Op, uint64_t InsertMask);
 
+  // Try to update RxSBG so that only the bits of RxSBG.Input in Mask are used.
+  // Return true on success.
+  bool refineRxSBGMask(RxSBGOperands &RxSBG, uint64_t Mask);
+
   // Try to fold some of RxSBG.Input into other fields of RxSBG.
   // Return true on success.
   bool expandRxSBG(RxSBGOperands &RxSBG);
@@ -607,52 +619,15 @@ bool SystemZDAGToDAGISel::detectOrAndInsertion(SDValue &Op,
   return true;
 }
 
-// Return true if Mask matches the regexp 0*1+0*, given that zero masks
-// have already been filtered out.  Store the first set bit in LSB and
-// the number of set bits in Length if so.
-static bool isStringOfOnes(uint64_t Mask, unsigned &LSB, unsigned &Length) {
-  unsigned First = findFirstSet(Mask);
-  uint64_t Top = (Mask >> First) + 1;
-  if ((Top & -Top) == Top) {
-    LSB = First;
-    Length = findFirstSet(Top);
-    return true;
-  }
-  return false;
-}
-
-// Try to update RxSBG so that only the bits of RxSBG.Input in Mask are used.
-// Return true on success.
-static bool refineRxSBGMask(RxSBGOperands &RxSBG, uint64_t Mask) {
+bool SystemZDAGToDAGISel::refineRxSBGMask(RxSBGOperands &RxSBG, uint64_t Mask) {
+  const SystemZInstrInfo *TII = getInstrInfo();
   if (RxSBG.Rotate != 0)
     Mask = (Mask << RxSBG.Rotate) | (Mask >> (64 - RxSBG.Rotate));
   Mask &= RxSBG.Mask;
-
-  // Reject trivial all-zero masks.
-  if (Mask == 0)
-    return false;
-
-  // Handle the 1+0+ or 0+1+0* cases.  Start then specifies the index of
-  // the msb and End specifies the index of the lsb.
-  unsigned LSB, Length;
-  if (isStringOfOnes(Mask, LSB, Length)) {
-    RxSBG.Mask = Mask;
-    RxSBG.Start = 63 - (LSB + Length - 1);
-    RxSBG.End = 63 - LSB;
-    return true;
-  }
-
-  // Handle the wrap-around 1+0+1+ cases.  Start then specifies the msb
-  // of the low 1s and End specifies the lsb of the high 1s.
-  if (isStringOfOnes(Mask ^ allOnes(RxSBG.BitSize), LSB, Length)) {
-    assert(LSB > 0 && "Bottom bit must be set");
-    assert(LSB + Length < RxSBG.BitSize && "Top bit must be set");
+  if (TII->isRxSBGMask(Mask, RxSBG.BitSize, RxSBG.Start, RxSBG.End)) {
     RxSBG.Mask = Mask;
-    RxSBG.Start = 63 - (LSB - 1);
-    RxSBG.End = 63 - (LSB + Length);
     return true;
   }
-
   return false;
 }
 
@@ -824,24 +799,38 @@ SDValue SystemZDAGToDAGISel::convertTo(SDLoc DL, EVT VT, SDValue N) {
 }
 
 SDNode *SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) {
+  EVT VT = N->getValueType(0);
   RxSBGOperands RISBG(SystemZ::RISBG, SDValue(N, 0));
   unsigned Count = 0;
   while (expandRxSBG(RISBG))
     Count += 1;
-  // Prefer to use normal shift instructions over RISBG, since they can handle
-  // all cases and are sometimes shorter.  Prefer to use RISBG for ANDs though,
-  // since it is effectively a three-operand instruction in this case,
-  // and since it can handle some masks that AND IMMEDIATE can't.
-  if (Count < (N->getOpcode() == ISD::AND ? 1U : 2U))
-    return 0;
-
-  // Prefer register extensions like LLC over RISBG.
-  if (RISBG.Rotate == 0 &&
-      (RISBG.Start == 32 || RISBG.Start == 48 || RISBG.Start == 56) &&
-      RISBG.End == 63)
+  if (Count == 0)
     return 0;
+  if (Count == 1) {
+    // Prefer to use normal shift instructions over RISBG, since they can handle
+    // all cases and are sometimes shorter.
+    if (N->getOpcode() != ISD::AND)
+      return 0;
+
+    // Prefer register extensions like LLC over RISBG.  Also prefer to start
+    // out with normal ANDs if one instruction would be enough.  We can convert
+    // these ANDs into an RISBG later if a three-address instruction is useful.
+    if (VT == MVT::i32 ||
+        RISBG.Mask == 0xff ||
+        RISBG.Mask == 0xffff ||
+        SystemZ::isImmLF(~RISBG.Mask) ||
+        SystemZ::isImmHF(~RISBG.Mask)) {
+      // Force the new mask into the DAG, since it may include known-one bits.
+      ConstantSDNode *MaskN = cast<ConstantSDNode>(N->getOperand(1).getNode());
+      if (MaskN->getZExtValue() != RISBG.Mask) {
+        SDValue NewMask = CurDAG->getConstant(RISBG.Mask, VT);
+        N = CurDAG->UpdateNodeOperands(N, N->getOperand(0), NewMask);
+        return SelectCode(N);
+      }
+      return 0;
+    }
+  }  
 
-  EVT VT = N->getValueType(0);
   SDValue Ops[5] = {
     getUNDEF64(SDLoc(N)),
     convertTo(SDLoc(N), MVT::i64, RISBG.Input),
index 26ea086aa3689291e161e0bb03e730fdf94dcd4a..12211fe2c24adb61685f6ca82fab68ff10e9d171 100644 (file)
 
 using namespace llvm;
 
+// Return a mask with Count low bits set.
+static uint64_t allOnes(unsigned int Count) {
+  return Count == 0 ? 0 : (uint64_t(1) << (Count - 1) << 1) - 1;
+}
+
 SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm)
   : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKDOWN, SystemZ::ADJCALLSTACKUP),
     RI(tm), TM(tm) {
@@ -507,6 +512,49 @@ static bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag) {
           MI->getOperand(3).getReg() == 0);
 }
 
+namespace {
+  struct LogicOp {
+    LogicOp() : RegSize(0), ImmLSB(0), ImmSize(0) {}
+    LogicOp(unsigned regSize, unsigned immLSB, unsigned immSize)
+      : RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {}
+
+    operator bool() const { return RegSize; }
+
+    unsigned RegSize, ImmLSB, ImmSize;
+  };
+}
+
+static LogicOp interpretAndImmediate(unsigned Opcode) {
+  switch (Opcode) {
+  case SystemZ::NILL32: return LogicOp(32,  0, 16);
+  case SystemZ::NILH32: return LogicOp(32, 16, 16);
+  case SystemZ::NILL:   return LogicOp(64,  0, 16);
+  case SystemZ::NILH:   return LogicOp(64, 16, 16);
+  case SystemZ::NIHL:   return LogicOp(64, 32, 16);
+  case SystemZ::NIHH:   return LogicOp(64, 48, 16);
+  case SystemZ::NILF32: return LogicOp(32,  0, 32);
+  case SystemZ::NILF:   return LogicOp(64,  0, 32);
+  case SystemZ::NIHF:   return LogicOp(64, 32, 32);
+  default:              return LogicOp();
+  }
+}
+
+// Used to return from convertToThreeAddress after replacing two-address
+// instruction OldMI with three-address instruction NewMI.
+static MachineInstr *finishConvertToThreeAddress(MachineInstr *OldMI,
+                                                 MachineInstr *NewMI,
+                                                 LiveVariables *LV) {
+  if (LV) {
+    unsigned NumOps = OldMI->getNumOperands();
+    for (unsigned I = 1; I < NumOps; ++I) {
+      MachineOperand &Op = OldMI->getOperand(I);
+      if (Op.isReg() && Op.isKill())
+        LV->replaceKillInstruction(Op.getReg(), OldMI, NewMI);
+    }
+  }
+  return NewMI;
+}
+
 MachineInstr *
 SystemZInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
                                         MachineBasicBlock::iterator &MBBI,
@@ -524,26 +572,50 @@ SystemZInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
   if (TM.getSubtargetImpl()->hasDistinctOps()) {
     int ThreeOperandOpcode = SystemZ::getThreeOperandOpcode(Opcode);
     if (ThreeOperandOpcode >= 0) {
-      unsigned DestReg = MI->getOperand(0).getReg();
+      MachineOperand &Dest = MI->getOperand(0);
       MachineOperand &Src = MI->getOperand(1);
-      MachineInstrBuilder MIB = BuildMI(*MBB, MBBI, MI->getDebugLoc(),
-                                        get(ThreeOperandOpcode), DestReg);
+      MachineInstrBuilder MIB =
+        BuildMI(*MBB, MBBI, MI->getDebugLoc(), get(ThreeOperandOpcode))
+        .addOperand(Dest);
       // Keep the kill state, but drop the tied flag.
-      MIB.addReg(Src.getReg(), getKillRegState(Src.isKill()));
+      MIB.addReg(Src.getReg(), getKillRegState(Src.isKill()), Src.getSubReg());
       // Keep the remaining operands as-is.
       for (unsigned I = 2; I < NumOps; ++I)
         MIB.addOperand(MI->getOperand(I));
-      MachineInstr *NewMI = MIB;
-
-      // Transfer killing information to the new instruction.
-      if (LV) {
-        for (unsigned I = 1; I < NumOps; ++I) {
-          MachineOperand &Op = MI->getOperand(I);
-          if (Op.isReg() && Op.isKill())
-            LV->replaceKillInstruction(Op.getReg(), MI, NewMI);
+      return finishConvertToThreeAddress(MI, MIB, LV);
+    }
+  }
+
+  // Try to convert an AND into an RISBG-type instruction.
+  if (LogicOp And = interpretAndImmediate(Opcode)) {
+    unsigned NewOpcode;
+    if (And.RegSize == 64)
+      NewOpcode = SystemZ::RISBG;
+    else if (TM.getSubtargetImpl()->hasHighWord())
+      NewOpcode = SystemZ::RISBLG32;
+    else
+      // We can't use RISBG for 32-bit operations because it clobbers the
+      // high word of the destination too.
+      NewOpcode = 0;
+    if (NewOpcode) {
+      uint64_t Imm = MI->getOperand(2).getImm() << And.ImmLSB;
+      // AND IMMEDIATE leaves the other bits of the register unchanged.
+      Imm |= allOnes(And.RegSize) & ~(allOnes(And.ImmSize) << And.ImmLSB);
+      unsigned Start, End;
+      if (isRxSBGMask(Imm, And.RegSize, Start, End)) {
+        if (NewOpcode == SystemZ::RISBLG32) {
+          Start &= 31;
+          End &= 31;
         }
+        MachineOperand &Dest = MI->getOperand(0);
+        MachineOperand &Src = MI->getOperand(1);
+        MachineInstrBuilder MIB =
+          BuildMI(*MBB, MI, MI->getDebugLoc(), get(NewOpcode))
+          .addOperand(Dest).addReg(0)
+          .addReg(Src.getReg(), getKillRegState(Src.isKill()), Src.getSubReg())
+          .addImm(Start).addImm(End + 128).addImm(0);
+        return finishConvertToThreeAddress(MI, MIB, LV);
       }
-      return MIB;
     }
   }
   return 0;
@@ -775,6 +847,48 @@ unsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode,
   return 0;
 }
 
+// Return true if Mask matches the regexp 0*1+0*, given that zero masks
+// have already been filtered out.  Store the first set bit in LSB and
+// the number of set bits in Length if so.
+static bool isStringOfOnes(uint64_t Mask, unsigned &LSB, unsigned &Length) {
+  unsigned First = findFirstSet(Mask);
+  uint64_t Top = (Mask >> First) + 1;
+  if ((Top & -Top) == Top) {
+    LSB = First;
+    Length = findFirstSet(Top);
+    return true;
+  }
+  return false;
+}
+
+bool SystemZInstrInfo::isRxSBGMask(uint64_t Mask, unsigned BitSize,
+                                   unsigned &Start, unsigned &End) const {
+  // Reject trivial all-zero masks.
+  if (Mask == 0)
+    return false;
+
+  // Handle the 1+0+ or 0+1+0* cases.  Start then specifies the index of
+  // the msb and End specifies the index of the lsb.
+  unsigned LSB, Length;
+  if (isStringOfOnes(Mask, LSB, Length)) {
+    Start = 63 - (LSB + Length - 1);
+    End = 63 - LSB;
+    return true;
+  }
+
+  // Handle the wrap-around 1+0+1+ cases.  Start then specifies the msb
+  // of the low 1s and End specifies the lsb of the high 1s.
+  if (isStringOfOnes(Mask ^ allOnes(BitSize), LSB, Length)) {
+    assert(LSB > 0 && "Bottom bit must be set");
+    assert(LSB + Length < BitSize && "Top bit must be set");
+    Start = 63 - (LSB - 1);
+    End = 63 - (LSB + Length);
+    return true;
+  }
+
+  return false;
+}
+
 unsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode,
                                                const MachineInstr *MI) const {
   switch (Opcode) {
index 7d11f39d24eaa57de462ce54d417f07844a7de01..7fc0ca9a7a6e6ed22a6798f47bad06b783b4265f 100644 (file)
@@ -187,6 +187,12 @@ public:
   // exists.
   unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const;
 
+  // Return true if ROTATE AND ... SELECTED BITS can be used to select bits
+  // Mask of the R2 operand, given that only the low BitSize bits of Mask are
+  // significant.  Set Start and End to the I3 and I4 operands if so.
+  bool isRxSBGMask(uint64_t Mask, unsigned BitSize,
+                   unsigned &Start, unsigned &End) const;
+
   // If Opcode is a COMPARE opcode for which an associated COMPARE AND
   // BRANCH exists, return the opcode for the latter, otherwise return 0.
   // MI, if nonnull, is the compare instruction.
index 6386d16b3d433dfe74c025ebdd50f7e9113d484e..b3ea36db7d606d4f097101b53bf13172db661fbd 100644 (file)
@@ -692,21 +692,23 @@ let Defs = [CC] in {
     defm NGR : BinaryRREAndK<"ng", 0xB980, 0xB9E4, and, GR64, GR64>;
   }
 
-  // ANDs of a 16-bit immediate, leaving other bits unaffected.
-  let isCodeGenOnly = 1 in {
-    def NILL32 : BinaryRI<"nill", 0xA57, and, GR32, imm32ll16c>;
-    def NILH32 : BinaryRI<"nilh", 0xA56, and, GR32, imm32lh16c>;
+  let isConvertibleToThreeAddress = 1 in {
+    // ANDs of a 16-bit immediate, leaving other bits unaffected.
+    let isCodeGenOnly = 1 in {
+      def NILL32 : BinaryRI<"nill", 0xA57, and, GR32, imm32ll16c>;
+      def NILH32 : BinaryRI<"nilh", 0xA56, and, GR32, imm32lh16c>;
+    }
+    def NILL : BinaryRI<"nill", 0xA57, and, GR64, imm64ll16c>;
+    def NILH : BinaryRI<"nilh", 0xA56, and, GR64, imm64lh16c>;
+    def NIHL : BinaryRI<"nihl", 0xA55, and, GR64, imm64hl16c>;
+    def NIHH : BinaryRI<"nihh", 0xA54, and, GR64, imm64hh16c>;
+
+    // ANDs of a 32-bit immediate, leaving other bits unaffected.
+    let isCodeGenOnly = 1 in
+      def NILF32 : BinaryRIL<"nilf", 0xC0B, and, GR32, uimm32>;
+    def NILF : BinaryRIL<"nilf", 0xC0B, and, GR64, imm64lf32c>;
+    def NIHF : BinaryRIL<"nihf", 0xC0A, and, GR64, imm64hf32c>;
   }
-  def NILL : BinaryRI<"nill", 0xA57, and, GR64, imm64ll16c>;
-  def NILH : BinaryRI<"nilh", 0xA56, and, GR64, imm64lh16c>;
-  def NIHL : BinaryRI<"nihl", 0xA55, and, GR64, imm64hl16c>;
-  def NIHH : BinaryRI<"nihh", 0xA54, and, GR64, imm64hh16c>;
-
-  // ANDs of a 32-bit immediate, leaving other bits unaffected.
-  let isCodeGenOnly = 1 in
-    def NILF32 : BinaryRIL<"nilf", 0xC0B, and, GR32, uimm32>;
-  def NILF : BinaryRIL<"nilf", 0xC0B, and, GR64, imm64lf32c>;
-  def NIHF : BinaryRIL<"nihf", 0xC0A, and, GR64, imm64hf32c>;
 
   // ANDs of memory.
   defm N  : BinaryRXPair<"n", 0x54, 0xE354, and, GR32, load, 4>;
@@ -869,6 +871,9 @@ let Defs = [CC] in {
 
 // Forms of RISBG that only affect one word of the destination register.
 // They do not set CC.
+let isCodeGenOnly = 1 in
+  def RISBLG32 : RotateSelectRIEf<"risblg", 0xEC51, GR32, GR32>,
+                 Requires<[FeatureHighWord]>;
 def RISBHG : RotateSelectRIEf<"risbhg", 0xEC5D, GR64, GR64>,
              Requires<[FeatureHighWord]>;
 def RISBLG : RotateSelectRIEf<"risblg", 0xEC51, GR64, GR64>,
index cf4ed891525d439f2e40ec94476083237e389567..d0960cdb1047aeee5daf21c46f9cda7c05f4f24a 100644 (file)
@@ -65,8 +65,8 @@ define void @f5(i64 %addr, i64 %index) {
 ; An address with an index and a displacement added using OR.
 define void @f6(i64 %addr, i64 %index) {
 ; CHECK-LABEL: f6:
-; CHECK: risbg [[BASE:%r[1245]]], %r2, 0, 188, 0
-; CHECK: lb %r0, 6(%r3,[[BASE]])
+; CHECK: nill %r2, 65528
+; CHECK: lb %r0, 6(%r3,%r2)
 ; CHECK: br %r14
   %aligned = and i64 %addr, -8
   %or = or i64 %aligned, 6
@@ -93,10 +93,10 @@ define void @f7(i64 %addr, i64 %index) {
 ; about the alignment of %add here.
 define void @f8(i64 %addr, i64 %index) {
 ; CHECK-LABEL: f8:
-; CHECK: risbg [[BASE:%r[1245]]], %r2, 0, 188, 0
-; CHECK: agr [[BASE]], %r3
-; CHECK: oill [[BASE]], 6
-; CHECK: lb %r0, 0([[BASE]])
+; CHECK: nill %r2, 65528
+; CHECK: agr %r2, %r3
+; CHECK: oill %r2, 6
+; CHECK: lb %r0, 0(%r2)
 ; CHECK: br %r14
   %aligned = and i64 %addr, -8
   %add = add i64 %aligned, %index
index 66a798679b9dcc1555b2ff45ccc3e69006b8b8da..56c48794b0721249376dae620b2dea3e43d41aad 100644 (file)
@@ -71,8 +71,8 @@ define void @f5(i64 %addr, i64 %index, i8 **%dst) {
 ; An address with an index and a displacement added using OR.
 define void @f6(i64 %addr, i64 %index, i8 **%dst) {
 ; CHECK-LABEL: f6:
-; CHECK: risbg [[BASE:%r[1245]]], %r2, 0, 188, 0
-; CHECK: lb %r0, 6(%r3,[[BASE]])
+; CHECK: nill %r2, 65528
+; CHECK: lb %r0, 6(%r3,%r2)
 ; CHECK: br %r14
   %aligned = and i64 %addr, -8
   %or = or i64 %aligned, 6
@@ -101,10 +101,10 @@ define void @f7(i64 %addr, i64 %index, i8 **%dst) {
 ; about the alignment of %add here.
 define void @f8(i64 %addr, i64 %index, i8 **%dst) {
 ; CHECK-LABEL: f8:
-; CHECK: risbg [[BASE:%r[1245]]], %r2, 0, 188, 0
-; CHECK: agr [[BASE]], %r3
-; CHECK: oill [[BASE]], 6
-; CHECK: lb %r0, 0([[BASE]])
+; CHECK: nill %r2, 65528
+; CHECK: agr %r2, %r3
+; CHECK: oill %r2, 6
+; CHECK: lb %r0, 0(%r2)
 ; CHECK: br %r14
   %aligned = and i64 %addr, -8
   %add = add i64 %aligned, %index
index 2cd9a3a2420789a08e20776c04089ba2fe4e38fd..2ddefd70cc9d298ee8a4927626e4115051ee18a5 100644 (file)
@@ -18,15 +18,15 @@ define i64 @f1(i64 %length, i64 %index) {
 ;
 ;    lgr %r1, %r15
 ;    sgr %r1, %r2
-;    risbg %r1, %r1, 0, 188, 0
+;    nill %r1, 0xfff8
 ;    lgr %r15, %r1
 ;
 ; CHECK-LABEL: f1:
 ; CHECK-DAG: la [[REG1:%r[0-5]]], 7(%r2)
-; CHECK-DAG: risbg [[REG2:%r[0-5]]], [[REG1]], 0, 188, 0
-; CHECK-DAG: lgr [[REG3:%r[0-5]]], %r15
-; CHECK: sgr [[REG3]], [[REG2]]
-; CHECK: lgr %r15, [[REG3]]
+; CHECK-DAG: nill [[REG1]], 65528
+; CHECK-DAG: lgr [[REG2:%r[0-5]]], %r15
+; CHECK: sgr [[REG2]], [[REG1]]
+; CHECK: lgr %r15, [[REG2]]
 ;
 ; CHECK-A-LABEL: f1:
 ; CHECK-A: lgr %r15, %r1
index 0f39e1851507f9c14b29a198190632c5eb4876bf..a7f08b7bb79036497fa9cccbbcb7d09294fd9ac1 100644 (file)
@@ -1,49 +1,49 @@
 ; Test 32-bit ANDs in which the second operand is constant.
 ;
-; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
 
-; ANDs with 1 should use RISBG
+; ANDs with 1 can use NILF.
 define i32 @f1(i32 %a) {
 ; CHECK-LABEL: f1:
-; CHECK: risbg %r2, %r2, 63, 191, 0
+; CHECK: nilf %r2, 1
 ; CHECK: br %r14
   %and = and i32 %a, 1
   ret i32 %and
 }
 
-; ...same for 2.
-define i32 @f2(i32 %a) {
+; ...but RISBLG is available as a three-address form.
+define i32 @f2(i32 %a, i32 %b) {
 ; CHECK-LABEL: f2:
-; CHECK: risbg %r2, %r2, 62, 190, 0
+; CHECK: risblg %r2, %r3, 31, 159, 0
 ; CHECK: br %r14
-  %and = and i32 %a, 2
+  %and = and i32 %b, 1
   ret i32 %and
 }
 
-; ...and 3.
-define i32 @f3(i32 %a) {
+; ...same for 4.
+define i32 @f3(i32 %a, i32 %b) {
 ; CHECK-LABEL: f3:
-; CHECK: risbg %r2, %r2, 62, 191, 0
+; CHECK: risblg %r2, %r3, 29, 157, 0
 ; CHECK: br %r14
-  %and = and i32 %a, 3
+  %and = and i32 %b, 4
   ret i32 %and
 }
 
-; ...and 4.
+; ANDs with 5 must use NILF.
 define i32 @f4(i32 %a) {
 ; CHECK-LABEL: f4:
-; CHECK: risbg %r2, %r2, 61, 189, 0
+; CHECK: nilf %r2, 5
 ; CHECK: br %r14
-  %and = and i32 %a, 4
+  %and = and i32 %a, 5
   ret i32 %and
 }
 
-; Check the lowest useful NILF value.
-define i32 @f5(i32 %a) {
+; ...a single RISBLG isn't enough.
+define i32 @f5(i32 %a, i32 %b) {
 ; CHECK-LABEL: f5:
-; CHECK: nilf %r2, 5
+; CHECK-NOT: risb
 ; CHECK: br %r14
-  %and = and i32 %a, 5
+  %and = and i32 %b, 5
   ret i32 %and
 }
 
@@ -56,174 +56,171 @@ define i32 @f6(i32 %a) {
   ret i32 %and
 }
 
-; ANDs of 0xffff are zero extensions from i16.
-define i32 @f7(i32 %a) {
+; ...a single RISBLG isn't enough.
+define i32 @f7(i32 %a, i32 %b) {
 ; CHECK-LABEL: f7:
-; CHECK: llhr %r2, %r2
+; CHECK-NOT: risb
 ; CHECK: br %r14
-  %and = and i32 %a, 65535
+  %and = and i32 %b, 65533
   ret i32 %and
 }
 
-; Check the next value up, which can use RISBG.
+; Check the next highest value, which can use NILF.
 define i32 @f8(i32 %a) {
 ; CHECK-LABEL: f8:
-; CHECK: risbg %r2, %r2, 47, 175, 0
+; CHECK: nilf %r2, 65534
 ; CHECK: br %r14
-  %and = and i32 %a, 65536
+  %and = and i32 %a, 65534
   ret i32 %and
 }
 
-; Check the next value up, which must again use NILF.
-define i32 @f9(i32 %a) {
+; ...although the three-address case should use RISBLG.
+define i32 @f9(i32 %a, i32 %b) {
 ; CHECK-LABEL: f9:
-; CHECK: nilf %r2, 65537
+; CHECK: risblg %r2, %r3, 16, 158, 0
 ; CHECK: br %r14
-  %and = and i32 %a, 65537
+  %and = and i32 %b, 65534
   ret i32 %and
 }
 
-; This value is in range of NILH, but we use RISBG instead.
-define i32 @f10(i32 %a) {
+; ANDs of 0xffff are zero extensions from i16.
+define i32 @f10(i32 %a, i32 %b) {
 ; CHECK-LABEL: f10:
-; CHECK: risbg %r2, %r2, 47, 191, 0
+; CHECK: llhr %r2, %r3
 ; CHECK: br %r14
-  %and = and i32 %a, 131071
+  %and = and i32 %b, 65535
   ret i32 %and
 }
 
-; Check the lowest useful NILH value.
+; Check the next value up, which must again use NILF.
 define i32 @f11(i32 %a) {
 ; CHECK-LABEL: f11:
-; CHECK: nilh %r2, 2
+; CHECK: nilf %r2, 65536
 ; CHECK: br %r14
-  %and = and i32 %a, 196607
+  %and = and i32 %a, 65536
   ret i32 %and
 }
 
-; Check the highest useful NILH value.
-define i32 @f12(i32 %a) {
+; ...but the three-address case can use RISBLG.
+define i32 @f12(i32 %a, i32 %b) {
 ; CHECK-LABEL: f12:
-; CHECK: nilh %r2, 65530
+; CHECK: risblg %r2, %r3, 15, 143, 0
 ; CHECK: br %r14
-  %and = and i32 %a, -327681
+  %and = and i32 %b, 65536
   ret i32 %and
 }
 
-; Check the equivalent of NILH of 65531, which can use RISBG.
+; Check the lowest useful NILH value.
 define i32 @f13(i32 %a) {
 ; CHECK-LABEL: f13:
-; CHECK: risbg %r2, %r2, 46, 172, 0
+; CHECK: nilh %r2, 1
 ; CHECK: br %r14
-  %and = and i32 %a, -262145
+  %and = and i32 %a, 131071
   ret i32 %and
 }
 
-; ...same for 65532.
-define i32 @f14(i32 %a) {
+; ...but RISBLG is OK in the three-address case.
+define i32 @f14(i32 %a, i32 %b) {
 ; CHECK-LABEL: f14:
-; CHECK: risbg %r2, %r2, 48, 173, 0
+; CHECK: risblg %r2, %r3, 15, 159, 0
 ; CHECK: br %r14
-  %and = and i32 %a, -196609
+  %and = and i32 %b, 131071
   ret i32 %and
 }
 
-; ...and 65533.
+; Check the highest useful NILF value.
 define i32 @f15(i32 %a) {
 ; CHECK-LABEL: f15:
-; CHECK: risbg %r2, %r2, 47, 173, 0
+; CHECK: nilf %r2, 4294901758
 ; CHECK: br %r14
-  %and = and i32 %a, -131073
+  %and = and i32 %a, -65538
   ret i32 %and
 }
 
-; Check the highest useful NILF value.
+; Check the next value up, which is the highest useful NILH value.
 define i32 @f16(i32 %a) {
 ; CHECK-LABEL: f16:
-; CHECK: nilf %r2, 4294901758
+; CHECK: nilh %r2, 65534
 ; CHECK: br %r14
-  %and = and i32 %a, -65538
+  %and = and i32 %a, -65537
   ret i32 %and
 }
 
-; Check the next value up, which is the equivalent of an NILH of 65534.
-; We use RISBG instead.
+; Check the next value up, which is the first useful NILL value.
 define i32 @f17(i32 %a) {
 ; CHECK-LABEL: f17:
-; CHECK: risbg %r2, %r2, 48, 174, 0
+; CHECK: nill %r2, 0
 ; CHECK: br %r14
-  %and = and i32 %a, -65537
+  %and = and i32 %a, -65536
   ret i32 %and
 }
 
-; Check the next value up, which can also use RISBG.
-define i32 @f18(i32 %a) {
+; ...although the three-address case should use RISBLG.
+define i32 @f18(i32 %a, i32 %b) {
 ; CHECK-LABEL: f18:
-; CHECK: risbg %r2, %r2, 32, 175, 0
+; CHECK: risblg %r2, %r3, 0, 143, 0
 ; CHECK: br %r14
-  %and = and i32 %a, -65536
+  %and = and i32 %b, -65536
   ret i32 %and
 }
 
-; ...and again.
+; Check the next value up again, which can still use NILL.
 define i32 @f19(i32 %a) {
 ; CHECK-LABEL: f19:
-; CHECK: risbg %r2, %r2, 63, 175, 0
+; CHECK: nill %r2, 1
 ; CHECK: br %r14
   %and = and i32 %a, -65535
   ret i32 %and
 }
 
-; Check the next value up again, which is the lowest useful NILL value.
-define i32 @f20(i32 %a) {
+; Check the next value up again, which cannot use RISBLG.
+define i32 @f20(i32 %a, i32 %b) {
 ; CHECK-LABEL: f20:
-; CHECK: nill %r2, 2
+; CHECK-NOT: risb
 ; CHECK: br %r14
-  %and = and i32 %a, -65534
+  %and = and i32 %b, -65534
   ret i32 %and
 }
 
-; Check the highest useful NILL value.
+; Check the last useful mask, which can use NILL.
 define i32 @f21(i32 %a) {
 ; CHECK-LABEL: f21:
-; CHECK: nill %r2, 65530
+; CHECK: nill %r2, 65534
 ; CHECK: br %r14
-  %and = and i32 %a, -6
+  %and = and i32 %a, -2
   ret i32 %and
 }
 
-; Check the next value up, which can use RISBG.
-define i32 @f22(i32 %a) {
+; ...or RISBLG for the three-address case.
+define i32 @f22(i32 %a, i32 %b) {
 ; CHECK-LABEL: f22:
-; CHECK: risbg %r2, %r2, 62, 188, 0
+; CHECK: risblg %r2, %r3, 0, 158, 0
 ; CHECK: br %r14
-  %and = and i32 %a, -5
+  %and = and i32 %b, -2
   ret i32 %and
 }
 
-; ...and again.
-define i32 @f23(i32 %a) {
+; Test that RISBLG can be used when inserting a non-wraparound mask
+; into another register.
+define i64 @f23(i64 %a, i32 %b) {
 ; CHECK-LABEL: f23:
-; CHECK: risbg %r2, %r2, 32, 189, 0
+; CHECK: risblg %r2, %r3, 30, 158, 0
 ; CHECK: br %r14
-  %and = and i32 %a, -4
-  ret i32 %and
+  %and1 = and i64 %a, -4294967296
+  %and2 = and i32 %b, 2
+  %ext = zext i32 %and2 to i64
+  %or = or i64 %and1, %ext
+  ret i64 %or
 }
 
-; ...and again.
-define i32 @f24(i32 %a) {
+; ...and when inserting a wrap-around mask.
+define i64 @f24(i64 %a, i32 %b) {
 ; CHECK-LABEL: f24:
-; CHECK: risbg %r2, %r2, 63, 189, 0
-; CHECK: br %r14
-  %and = and i32 %a, -3
-  ret i32 %and
-}
-
-; Check the last useful mask.
-define i32 @f25(i32 %a) {
-; CHECK-LABEL: f25:
-; CHECK: risbg %r2, %r2, 32, 190, 0
+; CHECK: risblg %r2, %r3, 30, 156
 ; CHECK: br %r14
-  %and = and i32 %a, -2
-  ret i32 %and
+  %and1 = and i64 %a, -4294967296
+  %and2 = and i32 %b, -5
+  %ext = zext i32 %and2 to i64
+  %or = or i64 %and1, %ext
+  ret i64 %or
 }
index 9c2f4a65d9f6f3d408140ff988076f3b9b5bc0ae..efb21f36425cd5b8943d1b3a657ca61abd1492ef 100644 (file)
@@ -21,11 +21,11 @@ define i64 @f2(i64 %a) {
 }
 
 ; ...but 0xffff is a 16-bit zero extension.
-define i64 @f3(i64 %a) {
+define i64 @f3(i64 %a, i64 %b) {
 ; CHECK-LABEL: f3:
-; CHECK: llghr %r2, %r2
+; CHECK: llghr %r2, %r3
 ; CHECK: br %r14
-  %and = and i64 %a, 65535
+  %and = and i64 %b, 65535
   ret i64 %and
 }
 
@@ -48,35 +48,44 @@ define i64 @f5(i64 %a) {
 }
 
 ; Check the next value up, which is a 32-bit zero extension.
-define i64 @f6(i64 %a) {
+define i64 @f6(i64 %a, i64 %b) {
 ; CHECK-LABEL: f6:
-; CHECK: llgfr %r2, %r2
+; CHECK: llgfr %r2, %r3
 ; CHECK: br %r14
-  %and = and i64 %a, 4294967295
+  %and = and i64 %b, 4294967295
   ret i64 %and
 }
 
-; Check the lowest useful NIHF value (0x00000002_ffffffff).
+; Check the lowest useful NIHF value (0x00000001_ffffffff).
 define i64 @f7(i64 %a) {
 ; CHECK-LABEL: f7:
-; CHECK: nihf %r2, 2
+; CHECK: nihf %r2, 1
 ; CHECK: br %r14
-  %and = and i64 %a, 12884901887
+  %and = and i64 %a, 8589934591
   ret i64 %and
 }
 
-; Check the lowest useful NIHH value (0x0002ffff_ffffffff).
-define i64 @f8(i64 %a) {
+; ...but RISBG can be used if a three-address form is useful.
+define i64 @f8(i64 %a, i64 %b) {
 ; CHECK-LABEL: f8:
-; CHECK: nihh %r2, 2
+; CHECK: risbg %r2, %r3, 31, 191, 0
 ; CHECK: br %r14
-  %and = and i64 %a, 844424930131967
+  %and = and i64 %b, 8589934591
   ret i64 %and
 }
 
-; Check the highest useful NIHH value (0xfffaffff_ffffffff).
+; Check the lowest NIHH value outside the RISBG range (0x0002ffff_ffffffff).
 define i64 @f9(i64 %a) {
 ; CHECK-LABEL: f9:
+; CHECK: nihh %r2, 2
+; CHECK: br %r14
+  %and = and i64 %a, 844424930131967
+  ret i64 %and
+}
+
+; Check the highest NIHH value outside the RISBG range (0xfffaffff_ffffffff).
+define i64 @f10(i64 %a) {
+; CHECK-LABEL: f10:
 ; CHECK: nihh %r2, 65530
 ; CHECK: br %r14
   %and = and i64 %a, -1407374883553281
@@ -84,44 +93,44 @@ define i64 @f9(i64 %a) {
 }
 
 ; Check the highest useful NIHF value (0xfffefffe_ffffffff).
-define i64 @f10(i64 %a) {
-; CHECK-LABEL: f10:
+define i64 @f11(i64 %a) {
+; CHECK-LABEL: f11:
 ; CHECK: nihf %r2, 4294901758
 ; CHECK: br %r14
   %and = and i64 %a, -281479271677953
   ret i64 %and
 }
 
-; Check the lowest useful NIHL value (0xffff0002_ffffffff).
-define i64 @f11(i64 %a) {
-; CHECK-LABEL: f11:
+; Check the lowest NIHL value outside the RISBG range (0xffff0002_ffffffff).
+define i64 @f12(i64 %a) {
+; CHECK-LABEL: f12:
 ; CHECK: nihl %r2, 2
 ; CHECK: br %r14
   %and = and i64 %a, -281462091808769
   ret i64 %and
 }
 
-; Check the highest useful NIHL value (0xfffffffa_ffffffff).
-define i64 @f12(i64 %a) {
-; CHECK-LABEL: f12:
+; Check the highest NIHL value outside the RISBG range (0xfffffffa_ffffffff).
+define i64 @f13(i64 %a) {
+; CHECK-LABEL: f13:
 ; CHECK: nihl %r2, 65530
 ; CHECK: br %r14
   %and = and i64 %a, -21474836481
   ret i64 %and
 }
 
-; Check the lowest useful NILF range (0xffffffff_00000002).
-define i64 @f13(i64 %a) {
-; CHECK-LABEL: f13:
+; Check the lowest NILF value outside the RISBG range (0xffffffff_00000002).
+define i64 @f14(i64 %a) {
+; CHECK-LABEL: f14:
 ; CHECK: nilf %r2, 2
 ; CHECK: br %r14
   %and = and i64 %a, -4294967294
   ret i64 %and
 }
 
-; Check the low end of the NILH range (0xffffffff_0002ffff).
-define i64 @f14(i64 %a) {
-; CHECK-LABEL: f14:
+; Check the lowest NILH value outside the RISBG range (0xffffffff_0002ffff).
+define i64 @f15(i64 %a) {
+; CHECK-LABEL: f15:
 ; CHECK: nilh %r2, 2
 ; CHECK: br %r14
   %and = and i64 %a, -4294770689
@@ -129,17 +138,17 @@ define i64 @f14(i64 %a) {
 }
 
 ; Check the next value up, which must use NILF.
-define i64 @f15(i64 %a) {
-; CHECK-LABEL: f15:
+define i64 @f16(i64 %a) {
+; CHECK-LABEL: f16:
 ; CHECK: nilf %r2, 196608
 ; CHECK: br %r14
   %and = and i64 %a, -4294770688
   ret i64 %and
 }
 
-; Check the highest useful NILH value (0xffffffff_fffaffff).
-define i64 @f16(i64 %a) {
-; CHECK-LABEL: f16:
+; Check the highest NILH value outside the RISBG range (0xffffffff_fffaffff).
+define i64 @f17(i64 %a) {
+; CHECK-LABEL: f17:
 ; CHECK: nilh %r2, 65530
 ; CHECK: br %r14
   %and = and i64 %a, -327681
@@ -147,26 +156,26 @@ define i64 @f16(i64 %a) {
 }
 
 ; Check the maximum useful NILF value (0xffffffff_fffefffe).
-define i64 @f17(i64 %a) {
-; CHECK-LABEL: f17:
+define i64 @f18(i64 %a) {
+; CHECK-LABEL: f18:
 ; CHECK: nilf %r2, 4294901758
 ; CHECK: br %r14
   %and = and i64 %a, -65538
   ret i64 %and
 }
 
-; Check the lowest useful NILL value (0xffffffff_ffff0002).
-define i64 @f18(i64 %a) {
-; CHECK-LABEL: f18:
+; Check the lowest NILL value outside the RISBG range (0xffffffff_ffff0002).
+define i64 @f19(i64 %a) {
+; CHECK-LABEL: f19:
 ; CHECK: nill %r2, 2
 ; CHECK: br %r14
   %and = and i64 %a, -65534
   ret i64 %and
 }
 
-; Check the highest useful NILL value.
-define i64 @f19(i64 %a) {
-; CHECK-LABEL: f19:
+; Check the highest NILL value outside the RISBG range.
+define i64 @f20(i64 %a) {
+; CHECK-LABEL: f20:
 ; CHECK: nill %r2, 65530
 ; CHECK: br %r14
   %and = and i64 %a, -6
index 2e1947fcf7659fd242b090a988e805c4e629321b..2c8598ddd22f680978223677fb60acbb658d79bc 100644 (file)
 ;   instructions.
 define i8 @f1(i8 *%src, i8 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: ar [[ROT]], %r3
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
@@ -48,14 +48,14 @@ define i8 @f1(i8 *%src, i8 %b) {
 ; Check the minimum signed value.  We add 0x80000000 to the rotated word.
 define i8 @f2(i8 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: afi [[ROT]], -2147483648
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
index 76f7c2ed6b6bfe74a5c8961debc6d0bc3ce4b65b..2aff860bd2a5e546b64e0f7795d71d75969f18b9 100644 (file)
 ;   instructions.
 define i16 @f1(i16 *%src, i16 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: ar [[ROT]], %r3
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
@@ -48,14 +48,14 @@ define i16 @f1(i16 *%src, i16 %b) {
 ; Check the minimum signed value.  We add 0x80000000 to the rotated word.
 define i16 @f2(i16 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: afi [[ROT]], -2147483648
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
index 243cf1573ed59c68783a9c146e71ca1b7583f304..5cb5aba7923199e8fb2216ff0ff7cec58b8d91c4 100644 (file)
 ;   independent of the other loop prologue instructions.
 define i8 @f1(i8 *%src, i8 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: nr [[ROT]], %r3
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
@@ -49,14 +49,14 @@ define i8 @f1(i8 *%src, i8 %b) {
 ; Check the minimum signed value.  We AND the rotated word with 0x80ffffff.
 define i8 @f2(i8 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: nilh [[ROT]], 33023
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
index 31247a335d94e48ef0c039947503a20c7f9af251..bc92db141e133bc5276ccf3903670334183b8b42 100644 (file)
 ;   independent of the other loop prologue instructions.
 define i16 @f1(i16 *%src, i16 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: nr [[ROT]], %r3
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
@@ -49,14 +49,14 @@ define i16 @f1(i16 *%src, i16 %b) {
 ; Check the minimum signed value.  We AND the rotated word with 0x8000ffff.
 define i16 @f2(i16 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: nilh [[ROT]], 32768
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
index b224423c0b35e06d750f6dc36c5c484a7834cef4..649eeebe5d655d00bc818d04ae8eb4edf0e02406 100644 (file)
@@ -16,7 +16,8 @@ define i64 @f1(i64 %dummy, i64 *%src, i64 %b) {
   ret i64 %res
 }
 
-; Check ANDs of 1, which must be done using a register.
+; Check ANDs of 1, which are done using a register.  (We could use RISBG
+; instead, but that isn't implemented yet.)
 define i64 @f2(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f2:
 ; CHECK: ngr
@@ -25,132 +26,145 @@ define i64 @f2(i64 %dummy, i64 *%src) {
   ret i64 %res
 }
 
-; Check the low end of the NIHF range.
+; Check the equivalent of NIHF with 1, which can use RISBG instead.
 define i64 @f3(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f3:
 ; CHECK: lg %r2, 0(%r3)
 ; CHECK: [[LABEL:\.[^:]*]]:
-; CHECK: lgr %r0, %r2
-; CHECK: nihf %r0, 0
+; CHECK: risbg %r0, %r2, 31, 191, 0
 ; CHECK: csg %r2, %r0, 0(%r3)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 4294967295 seq_cst
+  %res = atomicrmw and i64 *%src, i64 8589934591 seq_cst
   ret i64 %res
 }
 
-; Check the next value up, which must use a register.
+; Check the lowest NIHF value outside the range of RISBG.
 define i64 @f4(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f4:
-; CHECK: ngr
+; CHECK: lg %r2, 0(%r3)
+; CHECK: [[LABEL:\.[^:]*]]:
+; CHECK: lgr %r0, %r2
+; CHECK: nihf %r0, 2
+; CHECK: csg %r2, %r0, 0(%r3)
+; CHECK: jlh [[LABEL]]
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 4294967296 seq_cst
+  %res = atomicrmw and i64 *%src, i64 12884901887 seq_cst
   ret i64 %res
 }
 
-; Check the low end of the NIHH range.
+; Check the next value up, which must use a register.
 define i64 @f5(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f5:
-; CHECK: nihh %r0, 0
+; CHECK: ngr
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 281474976710655 seq_cst
+  %res = atomicrmw and i64 *%src, i64 12884901888 seq_cst
   ret i64 %res
 }
 
-; Check the next value up, which must use a register.
+; Check the lowest NIHH value outside the range of RISBG.
 define i64 @f6(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f6:
-; CHECK: ngr
+; CHECK: nihh {{%r[0-5]}}, 2
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 281474976710656 seq_cst
+  %res = atomicrmw and i64 *%src, i64 844424930131967 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NILL value.
+; Check the next value up, which must use a register.
 define i64 @f7(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f7:
-; CHECK: nill %r0, 65534
+; CHECK: ngr
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 -2 seq_cst
+  %res = atomicrmw and i64 *%src, i64 281474976710656 seq_cst
   ret i64 %res
 }
 
-; Check the low end of the NILL range.
+; Check the highest NILL value outside the range of RISBG.
 define i64 @f8(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f8:
-; CHECK: nill %r0, 0
+; CHECK: nill {{%r[0-5]}}, 65530
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 -65536 seq_cst
+  %res = atomicrmw and i64 *%src, i64 -6 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NILH value, which is one less than the above.
+; Check the lowest NILL value outside the range of RISBG.
 define i64 @f9(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f9:
-; CHECK: nilh %r0, 65534
+; CHECK: nill {{%r[0-5]}}, 2
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 -65537 seq_cst
+  %res = atomicrmw and i64 *%src, i64 -65534 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NILF value, which is one less than the above.
+; Check the highest useful NILF value.
 define i64 @f10(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f10:
-; CHECK: nilf %r0, 4294901758
+; CHECK: nilf {{%r[0-5]}}, 4294901758
 ; CHECK: br %r14
   %res = atomicrmw and i64 *%src, i64 -65538 seq_cst
   ret i64 %res
 }
 
-; Check the low end of the NILH range.
+; Check the highest NILH value outside the range of RISBG.
 define i64 @f11(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f11:
-; CHECK: nilh %r0, 0
+; CHECK: nilh {{%r[0-5]}}, 65530
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 -4294901761 seq_cst
+  %res = atomicrmw and i64 *%src, i64 -327681 seq_cst
   ret i64 %res
 }
 
-; Check the low end of the NILF range.
+; Check the lowest NILH value outside the range of RISBG.
 define i64 @f12(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f12:
-; CHECK: nilf %r0, 0
+; CHECK: nilh {{%r[0-5]}}, 2
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 -4294967296 seq_cst
+  %res = atomicrmw and i64 *%src, i64 -4294770689 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NIHL value, which is one less than the above.
+; Check the lowest NILF value outside the range of RISBG.
 define i64 @f13(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f13:
-; CHECK: nihl %r0, 65534
+; CHECK: nilf {{%r[0-5]}}, 2
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 -4294967297 seq_cst
+  %res = atomicrmw and i64 *%src, i64 -4294967294 seq_cst
   ret i64 %res
 }
 
-; Check the low end of the NIHL range.
+; Check the highest NIHL value outside the range of RISBG.
 define i64 @f14(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f14:
-; CHECK: nihl %r0, 0
+; CHECK: nihl {{%r[0-5]}}, 65530
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 -281470681743361 seq_cst
+  %res = atomicrmw and i64 *%src, i64 -21474836481 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NIHH value, which is 1<<32 less than the above.
+; Check the lowest NIHL value outside the range of RISBG.
 define i64 @f15(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f15:
-; CHECK: nihh %r0, 65534
+; CHECK: nihl {{%r[0-5]}}, 2
 ; CHECK: br %r14
-  %res = atomicrmw and i64 *%src, i64 -281474976710657 seq_cst
+  %res = atomicrmw and i64 *%src, i64 -281462091808769 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NIHF value, which is 1<<32 less than the above.
+; Check the highest NIHH value outside the range of RISBG.
 define i64 @f16(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f16:
-; CHECK: nihf %r0, 4294901758
+; CHECK: nihh {{%r[0-5]}}, 65530
+; CHECK: br %r14
+  %res = atomicrmw and i64 *%src, i64 -1407374883553281 seq_cst
+  ret i64 %res
+}
+
+; Check the highest useful NIHF value.
+define i64 @f17(i64 %dummy, i64 *%src) {
+; CHECK-LABEL: f17:
+; CHECK: nihf {{%r[0-5]}}, 4294901758
 ; CHECK: br %r14
   %res = atomicrmw and i64 *%src, i64 -281479271677953 seq_cst
   ret i64 %res
index 1a9db879396bbbfce47ba5cb484c87266f414507..7368758f6120c1119741186864ca9da215b68d7d 100644 (file)
 ;   independent of the other loop prologue instructions.
 define i8 @f1(i8 *%src, i8 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LOOP:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: crjle [[ROT]], %r3, [[KEEP:\..*]]
 ; CHECK: risbg [[ROT]], %r3, 32, 39, 0
 ; CHECK: [[KEEP]]:
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LOOP]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
@@ -50,16 +50,16 @@ define i8 @f1(i8 *%src, i8 %b) {
 ; Check signed maximum.
 define i8 @f2(i8 *%src, i8 %b) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LOOP:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: crjhe [[ROT]], %r3, [[KEEP:\..*]]
 ; CHECK: risbg [[ROT]], %r3, 32, 39, 0
 ; CHECK: [[KEEP]]:
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LOOP]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
@@ -86,9 +86,9 @@ define i8 @f2(i8 *%src, i8 %b) {
 ; Check unsigned minimum.
 define i8 @f3(i8 *%src, i8 %b) {
 ; CHECK-LABEL: f3:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LOOP:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: clr [[ROT]], %r3
@@ -96,7 +96,7 @@ define i8 @f3(i8 *%src, i8 %b) {
 ; CHECK: risbg [[ROT]], %r3, 32, 39, 0
 ; CHECK: [[KEEP]]:
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LOOP]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
@@ -123,9 +123,9 @@ define i8 @f3(i8 *%src, i8 %b) {
 ; Check unsigned maximum.
 define i8 @f4(i8 *%src, i8 %b) {
 ; CHECK-LABEL: f4:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LOOP:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: clr [[ROT]], %r3
@@ -133,7 +133,7 @@ define i8 @f4(i8 *%src, i8 %b) {
 ; CHECK: risbg [[ROT]], %r3, 32, 39, 0
 ; CHECK: [[KEEP]]:
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LOOP]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
index 2f6d3eddc0738628429f4eda764131228327cf03..e5541b532684e5dd5c19d756a3a6635f0de6bc0f 100644 (file)
 ;   independent of the other loop prologue instructions.
 define i16 @f1(i16 *%src, i16 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LOOP:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: crjle [[ROT]], %r3, [[KEEP:\..*]]
 ; CHECK: risbg [[ROT]], %r3, 32, 47, 0
 ; CHECK: [[KEEP]]:
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LOOP]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
@@ -50,16 +50,16 @@ define i16 @f1(i16 *%src, i16 %b) {
 ; Check signed maximum.
 define i16 @f2(i16 *%src, i16 %b) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LOOP:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: crjhe [[ROT]], %r3, [[KEEP:\..*]]
 ; CHECK: risbg [[ROT]], %r3, 32, 47, 0
 ; CHECK: [[KEEP]]:
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LOOP]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
@@ -86,9 +86,9 @@ define i16 @f2(i16 *%src, i16 %b) {
 ; Check unsigned minimum.
 define i16 @f3(i16 *%src, i16 %b) {
 ; CHECK-LABEL: f3:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LOOP:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: clr [[ROT]], %r3
@@ -96,7 +96,7 @@ define i16 @f3(i16 *%src, i16 %b) {
 ; CHECK: risbg [[ROT]], %r3, 32, 47, 0
 ; CHECK: [[KEEP]]:
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LOOP]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
@@ -123,9 +123,9 @@ define i16 @f3(i16 *%src, i16 %b) {
 ; Check unsigned maximum.
 define i16 @f4(i16 *%src, i16 %b) {
 ; CHECK-LABEL: f4:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LOOP:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: clr [[ROT]], %r3
@@ -133,7 +133,7 @@ define i16 @f4(i16 *%src, i16 %b) {
 ; CHECK: risbg [[ROT]], %r3, 32, 47, 0
 ; CHECK: [[KEEP]]:
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LOOP]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
index cdeeaba3c3a973a8b165737b486357523712a85f..ec81af21086acaff6c7fe73b8659bf3b7bb723ea 100644 (file)
 ;   independent of the other loop prologue instructions.
 define i8 @f1(i8 *%src, i8 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: nr [[ROT]], %r3
 ; CHECK: xilf [[ROT]], 4278190080
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
@@ -50,15 +50,15 @@ define i8 @f1(i8 *%src, i8 %b) {
 ; Check the minimum signed value.  We AND the rotated word with 0x80ffffff.
 define i8 @f2(i8 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: nilh [[ROT]], 33023
 ; CHECK: xilf [[ROT]], 4278190080
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
index 60fdbc782ddcf2c6798ff351a7bb7ade696f26c7..3396f68fa79f8331dfcdacd33886d3409067a630 100644 (file)
 ;   independent of the other loop prologue instructions.
 define i16 @f1(i16 *%src, i16 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: nr [[ROT]], %r3
 ; CHECK: xilf [[ROT]], 4294901760
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
@@ -50,15 +50,15 @@ define i16 @f1(i16 *%src, i16 %b) {
 ; Check the minimum signed value.  We AND the rotated word with 0x8000ffff.
 define i16 @f2(i16 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: nilh [[ROT]], 32768
 ; CHECK: xilf [[ROT]], 4294901760
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
index 907647106c8ba7bd9edcdbaa112ef13b93c225c8..cda7aa2673affb2575ce78cb4cf8a2a15a03f885 100644 (file)
@@ -18,7 +18,8 @@ define i64 @f1(i64 %dummy, i64 *%src, i64 %b) {
   ret i64 %res
 }
 
-; Check NANDs of 1, which must be done using a register.
+; Check NANDs of 1, which are done using a register.  (We could use RISBG
+; instead, but that isn't implemented yet.)
 define i64 @f2(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f2:
 ; CHECK: ngr
@@ -27,156 +28,149 @@ define i64 @f2(i64 %dummy, i64 *%src) {
   ret i64 %res
 }
 
-; Check the low end of the NIHF range.
+; Check the equivalent of NIHF with 1, which can use RISBG instead.
 define i64 @f3(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f3:
 ; CHECK: lg %r2, 0(%r3)
 ; CHECK: [[LABEL:\.[^:]*]]:
-; CHECK: lgr %r0, %r2
-; CHECK: nihf %r0, 0
+; CHECK: risbg %r0, %r2, 31, 191, 0
 ; CHECK: lcgr %r0, %r0
 ; CHECK: aghi %r0, -1
 ; CHECK: csg %r2, %r0, 0(%r3)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 4294967295 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 8589934591 seq_cst
   ret i64 %res
 }
 
-; Check the next value up, which must use a register.
+; Check the lowest NIHF value outside the range of RISBG.
 define i64 @f4(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f4:
-; CHECK: ngr
+; CHECK: lg %r2, 0(%r3)
+; CHECK: [[LABEL:\.[^:]*]]:
+; CHECK: lgr %r0, %r2
+; CHECK: nihf %r0, 2
+; CHECK: lcgr %r0, %r0
+; CHECK: aghi %r0, -1
+; CHECK: csg %r2, %r0, 0(%r3)
+; CHECK: jlh [[LABEL]]
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 4294967296 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 12884901887 seq_cst
   ret i64 %res
 }
 
-; Check the low end of the NIHH range.
+; Check the next value up, which must use a register.
 define i64 @f5(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f5:
-; CHECK: nihh %r0, 0
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: ngr
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 281474976710655 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 12884901888 seq_cst
   ret i64 %res
 }
 
-; Check the next value up, which must use a register.
+; Check the lowest NIHH value outside the range of RISBG.
 define i64 @f6(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f6:
-; CHECK: ngr
+; CHECK: nihh {{%r[0-5]}}, 2
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 281474976710656 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 844424930131967 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NILL value.
+; Check the next value up, which must use a register.
 define i64 @f7(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f7:
-; CHECK: nill %r0, 65534
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: ngr
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 -2 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 281474976710656 seq_cst
   ret i64 %res
 }
 
-; Check the low end of the NILL range.
+; Check the highest NILL value outside the range of RISBG.
 define i64 @f8(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f8:
-; CHECK: nill %r0, 0
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: nill {{%r[0-5]}}, 65530
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 -65536 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 -6 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NILH value, which is one less than the above.
+; Check the lowest NILL value outside the range of RISBG.
 define i64 @f9(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f9:
-; CHECK: nilh %r0, 65534
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: nill {{%r[0-5]}}, 2
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 -65537 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 -65534 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NILF value, which is one less than the above.
+; Check the highest useful NILF value.
 define i64 @f10(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f10:
-; CHECK: nilf %r0, 4294901758
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: nilf {{%r[0-5]}}, 4294901758
 ; CHECK: br %r14
   %res = atomicrmw nand i64 *%src, i64 -65538 seq_cst
   ret i64 %res
 }
 
-; Check the low end of the NILH range.
+; Check the highest NILH value outside the range of RISBG.
 define i64 @f11(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f11:
-; CHECK: nilh %r0, 0
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: nilh {{%r[0-5]}}, 65530
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 -4294901761 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 -327681 seq_cst
   ret i64 %res
 }
 
-; Check the low end of the NILF range.
+; Check the lowest NILH value outside the range of RISBG.
 define i64 @f12(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f12:
-; CHECK: nilf %r0, 0
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: nilh {{%r[0-5]}}, 2
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 -4294967296 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 -4294770689 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NIHL value, which is one less than the above.
+; Check the lowest NILF value outside the range of RISBG.
 define i64 @f13(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f13:
-; CHECK: nihl %r0, 65534
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: nilf {{%r[0-5]}}, 2
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 -4294967297 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 -4294967294 seq_cst
   ret i64 %res
 }
 
-; Check the low end of the NIHL range.
+; Check the highest NIHL value outside the range of RISBG.
 define i64 @f14(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f14:
-; CHECK: nihl %r0, 0
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: nihl {{%r[0-5]}}, 65530
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 -281470681743361 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 -21474836481 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NIHH value, which is 1<<32 less than the above.
+; Check the lowest NIHL value outside the range of RISBG.
 define i64 @f15(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f15:
-; CHECK: nihh %r0, 65534
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: nihl {{%r[0-5]}}, 2
 ; CHECK: br %r14
-  %res = atomicrmw nand i64 *%src, i64 -281474976710657 seq_cst
+  %res = atomicrmw nand i64 *%src, i64 -281462091808769 seq_cst
   ret i64 %res
 }
 
-; Check the highest useful NIHF value, which is 1<<32 less than the above.
+; Check the highest NIHH value outside the range of RISBG.
 define i64 @f16(i64 %dummy, i64 *%src) {
 ; CHECK-LABEL: f16:
-; CHECK: nihf %r0, 4294901758
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: nihh {{%r[0-5]}}, 65530
+; CHECK: br %r14
+  %res = atomicrmw nand i64 *%src, i64 -1407374883553281 seq_cst
+  ret i64 %res
+}
+
+; Check the highest useful NIHF value.
+define i64 @f17(i64 %dummy, i64 *%src) {
+; CHECK-LABEL: f17:
+; CHECK: nihf {{%r[0-5]}}, 4294901758
 ; CHECK: br %r14
   %res = atomicrmw nand i64 *%src, i64 -281479271677953 seq_cst
   ret i64 %res
index fe1beedce7495cfa2d721b25ae04ca314adbdfd9..bf4be43e3185b8bfab52cb7a7aea11870a3a5f01 100644 (file)
 ;   instructions.
 define i8 @f1(i8 *%src, i8 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: or [[ROT]], %r3
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
@@ -48,14 +48,14 @@ define i8 @f1(i8 *%src, i8 %b) {
 ; Check the minimum signed value.  We OR the rotated word with 0x80000000.
 define i8 @f2(i8 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: oilh [[ROT]], 32768
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
index 73bc282644422712ad390e996fcd356c62f0b965..726d9aaa35cc90f8048d1297f6fe2b999c9fd2e9 100644 (file)
 ;   instructions.
 define i16 @f1(i16 *%src, i16 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: or [[ROT]], %r3
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
@@ -48,14 +48,14 @@ define i16 @f1(i16 *%src, i16 %b) {
 ; Check the minimum signed value.  We OR the rotated word with 0x80000000.
 define i16 @f2(i16 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: oilh [[ROT]], 32768
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
index e1060e05517d7bfdd1adbc63e17e678cb0504e3b..6d42545631e74c97717cb147deec2c2b55b740ff 100644 (file)
 ;   instructions.
 define i8 @f1(i8 *%src, i8 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: sr [[ROT]], %r3
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
@@ -48,14 +48,14 @@ define i8 @f1(i8 *%src, i8 %b) {
 ; Check the minimum signed value.  We add 0x80000000 to the rotated word.
 define i8 @f2(i8 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: afi [[ROT]], -2147483648
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
index 499a606f0b6640e2cff46ed7a013a31de58441eb..6f8e26e5c08895b8000855e77eb8f03c8fc60954 100644 (file)
 ;   instructions.
 define i16 @f1(i16 *%src, i16 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: sr [[ROT]], %r3
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
@@ -48,14 +48,14 @@ define i16 @f1(i16 *%src, i16 %b) {
 ; Check the minimum signed value.  We add 0x80000000 to the rotated word.
 define i16 @f2(i16 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: afi [[ROT]], -2147483648
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
index d83408f2588ab6d79ea38655a6c3079b9136f7bc..238ce336ac44f695db4b35629311f581b2e5c9a9 100644 (file)
 ;   which shift %r3 left so that %b is at the high end of the word).
 define i8 @f1(i8 *%src, i8 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: risbg [[ROT]], %r3, 32, 39, 24
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
index b00b341d4fcb427564275a05dfc399220c77cd92..635d9d440d21151b3614ec4b3aa293fc378eb62e 100644 (file)
 ;   which shift %r3 left so that %b is at the high end of the word).
 define i16 @f1(i16 *%src, i16 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: risbg [[ROT]], %r3, 32, 47, 16
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
index b457a6087322be28ffd97ef0e8ae39ff40827e42..969e3ef87c4af4eff378eb3eaceb21a4210a56fc 100644 (file)
 ;   instructions.
 define i8 @f1(i8 *%src, i8 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: xr [[ROT]], %r3
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
@@ -48,14 +48,14 @@ define i8 @f1(i8 *%src, i8 %b) {
 ; Check the minimum signed value.  We XOR the rotated word with 0x80000000.
 define i8 @f2(i8 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: xilf [[ROT]], 2147483648
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK: br %r14
index fa38d7027f5221e853cb0b3c9e4ca460c47f23c1..10d2e3f592b4365a78e0458a711c2f38fe9e0a5b 100644 (file)
 ;   instructions.
 define i16 @f1(i16 *%src, i16 %b) {
 ; CHECK-LABEL: f1:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: xr [[ROT]], %r3
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
@@ -48,14 +48,14 @@ define i16 @f1(i16 *%src, i16 %b) {
 ; Check the minimum signed value.  We XOR the rotated word with 0x80000000.
 define i16 @f2(i16 *%src) {
 ; CHECK-LABEL: f2:
-; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
-; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
-; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
+; CHECK: nill %r2, 65532
+; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
 ; CHECK: xilf [[ROT]], 2147483648
 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0([[NEGSHIFT:%r[1-9]+]])
-; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
 ; CHECK: jlh [[LABEL]]
 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK: br %r14
index c6f10380c2f7bb1a94bcca7d72e1ff6820a16dbb..467fe68be3e950d015a2da1cf720b8822a2e680c 100644 (file)
 ;   which shift %r3 left so that %b is at the high end of the word).
 define i8 @f1(i8 %dummy, i8 *%src, i8 %cmp, i8 %swap) {
 ; CHECK-MAIN-LABEL: f1:
-; CHECK-MAIN-DAG: sllg [[SHIFT:%r[1-9]+]], %r3, 3
-; CHECK-MAIN-DAG: risbg [[BASE:%r[1-9]+]], %r3, 0, 189, 0
-; CHECK-MAIN: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK-MAIN: sllg [[SHIFT:%r[1-9]+]], %r3, 3
+; CHECK-MAIN: nill %r3, 65532
+; CHECK-MAIN: l [[OLD:%r[0-9]+]], 0(%r3)
 ; CHECK-MAIN: [[LOOP:\.[^ ]*]]:
 ; CHECK-MAIN: rll %r2, [[OLD]], 8([[SHIFT]])
 ; CHECK-MAIN: risbg %r4, %r2, 32, 55, 0
 ; CHECK-MAIN: crjlh %r2, %r4, [[EXIT:\.[^ ]*]]
 ; CHECK-MAIN: risbg %r5, %r2, 32, 55, 0
 ; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r5, -8({{%r[1-9]+}})
-; CHECK-MAIN: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK-MAIN: cs [[OLD]], [[NEW]], 0(%r3)
 ; CHECK-MAIN: jlh [[LOOP]]
 ; CHECK-MAIN: [[EXIT]]:
 ; CHECK-MAIN-NOT: %r2
index fa2d088295b043b4d493633987bd876d6bc6b860..c7ee898ce277c764df28124d164d9b3326bc09a0 100644 (file)
 ;   which shift %r3 left so that %b is at the high end of the word).
 define i16 @f1(i16 %dummy, i16 *%src, i16 %cmp, i16 %swap) {
 ; CHECK-MAIN-LABEL: f1:
-; CHECK-MAIN-DAG: sllg [[SHIFT:%r[1-9]+]], %r3, 3
-; CHECK-MAIN-DAG: risbg [[BASE:%r[1-9]+]], %r3, 0, 189, 0
-; CHECK-MAIN: l [[OLD:%r[0-9]+]], 0([[BASE]])
+; CHECK-MAIN: sllg [[SHIFT:%r[1-9]+]], %r3, 3
+; CHECK-MAIN: nill %r3, 65532
+; CHECK-MAIN: l [[OLD:%r[0-9]+]], 0(%r3)
 ; CHECK-MAIN: [[LOOP:\.[^ ]*]]:
 ; CHECK-MAIN: rll %r2, [[OLD]], 16([[SHIFT]])
 ; CHECK-MAIN: risbg %r4, %r2, 32, 47, 0
 ; CHECK-MAIN: crjlh %r2, %r4, [[EXIT:\.[^ ]*]]
 ; CHECK-MAIN: risbg %r5, %r2, 32, 47, 0
 ; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r5, -16({{%r[1-9]+}})
-; CHECK-MAIN: cs [[OLD]], [[NEW]], 0([[BASE]])
+; CHECK-MAIN: cs [[OLD]], [[NEW]], 0(%r3)
 ; CHECK-MAIN: jlh [[LOOP]]
 ; CHECK-MAIN: [[EXIT]]:
 ; CHECK-MAIN-NOT: %r2
index b6fc0d58337f1594bc35a3b66be35dbbbde91a67..b4f042859a016f98a4d68bafb19833e3c0456321 100644 (file)
@@ -44,9 +44,9 @@ define float @f3(i64 %big) {
 define float @f4(i64 %big) {
 ; CHECK-LABEL: f4:
 ; CHECK-NOT: %r2
-; CHECK: risbg [[REG:%r[0-5]]], %r2, 0, 159, 0
-; CHECK-NOT: [[REG]]
-; CHECK: ldgr %f0, [[REG]]
+; CHECK: nilf %r2, 0
+; CHECK-NOT: %r2
+; CHECK: ldgr %f0, %r2
   %shift = ashr i64 %big, 32
   %a = trunc i64 %shift to i32
   %res = bitcast i32 %a to float
index 5f14b2919e135a3e1d3184d1c0e23f2c90fff0e6..0b54e85dc4edb5e5e5a941e96824d21dcccb55f5 100644 (file)
@@ -33,7 +33,7 @@ define i32 @f2(i32 %orig, i8 *%ptr) {
 ; register value.  We can use IC but must keep the original mask.
 define i32 @f3(i32 %orig, i8 *%ptr) {
 ; CHECK-LABEL: f3:
-; CHECK: risbg %r2, %r2, 32, 182, 0
+; CHECK: nill %r2, 65024
 ; CHECK: ic %r2, 0(%r3)
 ; CHECK: br %r14
   %val = load i8 *%ptr
@@ -46,7 +46,7 @@ define i32 @f3(i32 %orig, i8 *%ptr) {
 ; Like f3, but with the operands reversed.
 define i32 @f4(i32 %orig, i8 *%ptr) {
 ; CHECK-LABEL: f4:
-; CHECK: risbg %r2, %r2, 32, 182, 0
+; CHECK: nill %r2, 65024
 ; CHECK: ic %r2, 0(%r3)
 ; CHECK: br %r14
   %val = load i8 *%ptr
index 05958a65dc24cc731184f8ce78cf210b022a488a..7a85b0bee4d84ba850b53af798ee2326d24e9fb6 100644 (file)
@@ -33,7 +33,7 @@ define i64 @f2(i64 %orig, i8 *%ptr) {
 ; register value.  We can use IC but must keep the original mask.
 define i64 @f3(i64 %orig, i8 *%ptr) {
 ; CHECK-LABEL: f3:
-; CHECK: risbg %r2, %r2, 0, 182, 0
+; CHECK: nill %r2, 65024
 ; CHECK: ic %r2, 0(%r3)
 ; CHECK: br %r14
   %val = load i8 *%ptr
@@ -46,7 +46,7 @@ define i64 @f3(i64 %orig, i8 *%ptr) {
 ; Like f3, but with the operands reversed.
 define i64 @f4(i64 %orig, i8 *%ptr) {
 ; CHECK-LABEL: f4:
-; CHECK: risbg %r2, %r2, 0, 182, 0
+; CHECK: nill %r2, 65024
 ; CHECK: ic %r2, 0(%r3)
 ; CHECK: br %r14
   %val = load i8 *%ptr
index 6f89fefd9fe93ea30f658fb7e7c1e96604eb8465..85de6dc6af2c2c9af186b0305725d8556c8b1df8 100644 (file)
@@ -63,12 +63,12 @@ define i64 @f6(i64 %foo) {
   ret i64 %and
 }
 
-; Try the next value up (mask ....1111001).  The mask itself is suitable
-; for RISBG, but the shift is still needed.
+; Try the next value up (mask ....1111001).  This needs a separate shift
+; and mask.
 define i32 @f7(i32 %foo) {
 ; CHECK-LABEL: f7:
 ; CHECK: srl %r2, 2
-; CHECK: risbg %r2, %r2, 63, 188, 0
+; CHECK: nill %r2, 65529
 ; CHECK: br %r14
   %shr = lshr i32 %foo, 2
   %and = and i32 %shr, -7
@@ -78,8 +78,8 @@ define i32 @f7(i32 %foo) {
 ; ...and again with i64.
 define i64 @f8(i64 %foo) {
 ; CHECK-LABEL: f8:
-; CHECK: srlg [[REG:%r[0-5]]], %r2, 2
-; CHECK: risbg %r2, [[REG]], 63, 188, 0
+; CHECK: srlg %r2, %r2, 2
+; CHECK: nill %r2, 65529
 ; CHECK: br %r14
   %shr = lshr i64 %foo, 2
   %and = and i64 %shr, -7
@@ -107,12 +107,12 @@ define i64 @f10(i64 %foo) {
   ret i64 %and
 }
 
-; Try a wrap-around mask (mask ....111100001111).  The mask itself is suitable
-; for RISBG, but the shift is still needed.
+; Try a wrap-around mask (mask ....111100001111).  This needs a separate shift
+; and mask.
 define i32 @f11(i32 %foo) {
 ; CHECK-LABEL: f11:
 ; CHECK: sll %r2, 2
-; CHECK: risbg %r2, %r2, 60, 183, 0
+; CHECK: nill %r2, 65295
 ; CHECK: br %r14
   %shr = shl i32 %foo, 2
   %and = and i32 %shr, -241
@@ -122,8 +122,8 @@ define i32 @f11(i32 %foo) {
 ; ...and again with i64.
 define i64 @f12(i64 %foo) {
 ; CHECK-LABEL: f12:
-; CHECK: sllg [[REG:%r[0-5]]], %r2, 2
-; CHECK: risbg %r2, [[REG]], 60, 183, 0
+; CHECK: sllg %r2, %r2, 2
+; CHECK: nill %r2, 65295
 ; CHECK: br %r14
   %shr = shl i64 %foo, 2
   %and = and i64 %shr, -241
@@ -181,12 +181,11 @@ define i64 @f16(i64 %foo) {
 }
 
 ; Test a 32-bit rotate in which both parts of the OR are needed.
-; This needs a separate shift (although RISBLG would be better
-; if supported).
+; This needs a separate shift and mask.
 define i32 @f17(i32 %foo) {
 ; CHECK-LABEL: f17:
-; CHECK: rll [[REG:%r[0-5]]], %r2, 4
-; CHECK: risbg %r2, [[REG]], 57, 190, 0
+; CHECK: rll %r2, %r2, 4
+; CHECK: nilf %r2, 126
 ; CHECK: br %r14
   %parta = shl i32 %foo, 4
   %partb = lshr i32 %foo, 28
@@ -208,18 +207,18 @@ define i64 @f18(i64 %foo) {
 }
 
 ; Test an arithmetic shift right in which some of the sign bits are kept.
-; The SRA is still needed.
+; This needs a separate shift and mask.
 define i32 @f19(i32 %foo) {
 ; CHECK-LABEL: f19:
 ; CHECK: sra %r2, 28
-; CHECK: risbg %r2, %r2, 59, 190, 0
+; CHECK: nilf %r2, 30
 ; CHECK: br %r14
   %shr = ashr i32 %foo, 28
   %and = and i32 %shr, 30
   ret i32 %and
 }
 
-; ...and again with i64.
+; ...and again with i64.  In this case RISBG is the best way of doing the AND.
 define i64 @f20(i64 %foo) {
 ; CHECK-LABEL: f20:
 ; CHECK: srag [[REG:%r[0-5]]], %r2, 60
@@ -265,11 +264,12 @@ define i64 @f23(i64 %foo) {
   ret i64 %and
 }
 
-; Test a case where the AND comes before a rotate.
+; Test a case where the AND comes before a rotate.  This needs a separate
+; mask and rotate.
 define i32 @f24(i32 %foo) {
 ; CHECK-LABEL: f24:
-; CHECK: risbg [[REG:%r[0-5]]], %r2, 60, 190, 0
-; CHECK: rll %r2, [[REG]], 3
+; CHECK: nilf %r2, 14
+; CHECK: rll %r2, %r2, 3
 ; CHECK: br %r14
   %and = and i32 %foo, 14
   %parta = shl i32 %and, 3
@@ -290,11 +290,12 @@ define i64 @f25(i64 %foo) {
   ret i64 %rotl
 }
 
-; Test a wrap-around case in which the rotate comes after the AND.
+; Test a wrap-around case in which the AND comes before a rotate.
+; This again needs a separate mask and rotate.
 define i32 @f26(i32 %foo) {
 ; CHECK-LABEL: f26:
-; CHECK: risbg [[REG:%r[0-5]]], %r2, 60, 185, 0
-; CHECK: rll %r2, [[REG]], 5
+; CHECK: nill %r2, 65487
+; CHECK: rll %r2, %r2, 5
 ; CHECK: br %r14
   %and = and i32 %foo, -49
   %parta = shl i32 %and, 5