diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index 8866253484e..b7e966ff011 100644 --- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -132,6 +132,14 @@ class SystemZDAGToDAGISel : public SelectionDAGISel { return CurDAG->getTargetConstant(Imm, Node->getValueType(0)); } + const SystemZTargetMachine &getTargetMachine() const { + return static_cast(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)) { + if (TII->isRxSBGMask(Mask, RxSBG.BitSize, RxSBG.Start, RxSBG.End)) { 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"); - 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)) + 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. - if (RISBG.Rotate == 0 && - (RISBG.Start == 32 || RISBG.Start == 48 || RISBG.Start == 56) && - RISBG.End == 63) - 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(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), diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index 26ea086aa36..12211fe2c24 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -23,6 +23,11 @@ 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; + return finishConvertToThreeAddress(MI, MIB, LV); + } + } - // 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); + // 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) { diff --git a/lib/Target/SystemZ/SystemZInstrInfo.h b/lib/Target/SystemZ/SystemZInstrInfo.h index 7d11f39d24e..7fc0ca9a7a6 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/lib/Target/SystemZ/SystemZInstrInfo.h @@ -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. diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 6386d16b3d4..b3ea36db7d6 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -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>; - } - 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>; + 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>; + // 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>, diff --git a/test/CodeGen/SystemZ/addr-01.ll b/test/CodeGen/SystemZ/addr-01.ll index cf4ed891525..d0960cdb104 100644 --- a/test/CodeGen/SystemZ/addr-01.ll +++ b/test/CodeGen/SystemZ/addr-01.ll @@ -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 diff --git a/test/CodeGen/SystemZ/addr-02.ll b/test/CodeGen/SystemZ/addr-02.ll index 66a798679b9..56c48794b07 100644 --- a/test/CodeGen/SystemZ/addr-02.ll +++ b/test/CodeGen/SystemZ/addr-02.ll @@ -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 diff --git a/test/CodeGen/SystemZ/alloca-01.ll b/test/CodeGen/SystemZ/alloca-01.ll index 2cd9a3a2420..2ddefd70cc9 100644 --- a/test/CodeGen/SystemZ/alloca-01.ll +++ b/test/CodeGen/SystemZ/alloca-01.ll @@ -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 diff --git a/test/CodeGen/SystemZ/and-02.ll b/test/CodeGen/SystemZ/and-02.ll index 0f39e185150..a7f08b7bb79 100644 --- a/test/CodeGen/SystemZ/and-02.ll +++ b/test/CodeGen/SystemZ/and-02.ll @@ -1,52 +1,52 @@ ; 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: br %r14 - %and = and i32 %a, 4 - ret i32 %and -} - -; Check the lowest useful NILF value. -define i32 @f5(i32 %a) { -; CHECK-LABEL: f5: ; CHECK: nilf %r2, 5 ; CHECK: br %r14 %and = and i32 %a, 5 ret i32 %and } +; ...a single RISBLG isn't enough. +define i32 @f5(i32 %a, i32 %b) { +; CHECK-LABEL: f5: +; CHECK-NOT: risb +; CHECK: br %r14 + %and = and i32 %b, 5 + ret i32 %and +} + ; Check the highest 16-bit constant that must be handled by NILF. define i32 @f6(i32 %a) { ; CHECK-LABEL: f6: @@ -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, 65534 + ret i32 %and +} + +; ...although the three-address case should use RISBLG. +define i32 @f9(i32 %a, i32 %b) { +; CHECK-LABEL: f9: +; CHECK: risblg %r2, %r3, 16, 158, 0 +; CHECK: br %r14 + %and = and i32 %b, 65534 + ret i32 %and +} + +; ANDs of 0xffff are zero extensions from i16. +define i32 @f10(i32 %a, i32 %b) { +; CHECK-LABEL: f10: +; CHECK: llhr %r2, %r3 +; CHECK: br %r14 + %and = and i32 %b, 65535 + ret i32 %and +} + +; Check the next value up, which must again use NILF. +define i32 @f11(i32 %a) { +; CHECK-LABEL: f11: +; CHECK: nilf %r2, 65536 ; CHECK: br %r14 %and = and i32 %a, 65536 ret i32 %and } -; Check the next value up, which must again use NILF. -define i32 @f9(i32 %a) { -; CHECK-LABEL: f9: -; CHECK: nilf %r2, 65537 +; ...but the three-address case can use RISBLG. +define i32 @f12(i32 %a, i32 %b) { +; CHECK-LABEL: f12: +; CHECK: risblg %r2, %r3, 15, 143, 0 ; CHECK: br %r14 - %and = and i32 %a, 65537 + %and = and i32 %b, 65536 ret i32 %and } -; This value is in range of NILH, but we use RISBG instead. -define i32 @f10(i32 %a) { -; CHECK-LABEL: f10: -; CHECK: risbg %r2, %r2, 47, 191, 0 +; Check the lowest useful NILH value. +define i32 @f13(i32 %a) { +; CHECK-LABEL: f13: +; CHECK: nilh %r2, 1 ; CHECK: br %r14 %and = and i32 %a, 131071 ret i32 %and } -; Check the lowest useful NILH value. -define i32 @f11(i32 %a) { -; CHECK-LABEL: f11: -; CHECK: nilh %r2, 2 -; CHECK: br %r14 - %and = and i32 %a, 196607 - ret i32 %and -} - -; Check the highest useful NILH value. -define i32 @f12(i32 %a) { -; CHECK-LABEL: f12: -; CHECK: nilh %r2, 65530 -; CHECK: br %r14 - %and = and i32 %a, -327681 - ret i32 %and -} - -; Check the equivalent of NILH of 65531, which can use RISBG. -define i32 @f13(i32 %a) { -; CHECK-LABEL: f13: -; CHECK: risbg %r2, %r2, 46, 172, 0 -; CHECK: br %r14 - %and = and i32 %a, -262145 - 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 - ret i32 %and -} - -; ...and 65533. -define i32 @f15(i32 %a) { -; CHECK-LABEL: f15: -; CHECK: risbg %r2, %r2, 47, 173, 0 -; CHECK: br %r14 - %and = and i32 %a, -131073 + %and = and i32 %b, 131071 ret i32 %and } ; Check the highest useful NILF value. -define i32 @f16(i32 %a) { -; CHECK-LABEL: f16: +define i32 @f15(i32 %a) { +; CHECK-LABEL: f15: ; CHECK: nilf %r2, 4294901758 ; CHECK: br %r14 %and = and i32 %a, -65538 ret i32 %and } -; Check the next value up, which is the equivalent of an NILH of 65534. -; We use RISBG instead. -define i32 @f17(i32 %a) { -; CHECK-LABEL: f17: -; CHECK: risbg %r2, %r2, 48, 174, 0 +; Check the next value up, which is the highest useful NILH value. +define i32 @f16(i32 %a) { +; CHECK-LABEL: f16: +; CHECK: nilh %r2, 65534 ; CHECK: br %r14 %and = and i32 %a, -65537 ret i32 %and } -; Check the next value up, which can also use RISBG. -define i32 @f18(i32 %a) { -; CHECK-LABEL: f18: -; CHECK: risbg %r2, %r2, 32, 175, 0 +; Check the next value up, which is the first useful NILL value. +define i32 @f17(i32 %a) { +; CHECK-LABEL: f17: +; CHECK: nill %r2, 0 ; CHECK: br %r14 %and = and i32 %a, -65536 ret i32 %and } -; ...and again. +; ...although the three-address case should use RISBLG. +define i32 @f18(i32 %a, i32 %b) { +; CHECK-LABEL: f18: +; CHECK: risblg %r2, %r3, 0, 143, 0 +; CHECK: br %r14 + %and = and i32 %b, -65536 + ret i32 %and +} + +; 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: br %r14 - %and = and i32 %a, -6 - ret i32 %and -} - -; Check the next value up, which can use RISBG. -define i32 @f22(i32 %a) { -; CHECK-LABEL: f22: -; CHECK: risbg %r2, %r2, 62, 188, 0 -; CHECK: br %r14 - %and = and i32 %a, -5 - ret i32 %and -} - -; ...and again. -define i32 @f23(i32 %a) { -; CHECK-LABEL: f23: -; CHECK: risbg %r2, %r2, 32, 189, 0 -; CHECK: br %r14 - %and = and i32 %a, -4 - ret i32 %and -} - -; ...and again. -define i32 @f24(i32 %a) { -; 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: nill %r2, 65534 ; CHECK: br %r14 %and = and i32 %a, -2 ret i32 %and } + +; ...or RISBLG for the three-address case. +define i32 @f22(i32 %a, i32 %b) { +; CHECK-LABEL: f22: +; CHECK: risblg %r2, %r3, 0, 158, 0 +; CHECK: br %r14 + %and = and i32 %b, -2 + ret i32 %and +} + +; 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: risblg %r2, %r3, 30, 158, 0 +; CHECK: br %r14 + %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 when inserting a wrap-around mask. +define i64 @f24(i64 %a, i32 %b) { +; CHECK-LABEL: f24: +; CHECK: risblg %r2, %r3, 30, 156 +; CHECK: br %r14 + %and1 = and i64 %a, -4294967296 + %and2 = and i32 %b, -5 + %ext = zext i32 %and2 to i64 + %or = or i64 %and1, %ext + ret i64 %or +} diff --git a/test/CodeGen/SystemZ/and-04.ll b/test/CodeGen/SystemZ/and-04.ll index 9c2f4a65d9f..efb21f36425 100644 --- a/test/CodeGen/SystemZ/and-04.ll +++ b/test/CodeGen/SystemZ/and-04.ll @@ -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: risbg %r2, %r3, 31, 191, 0 +; CHECK: br %r14 + %and = and i64 %b, 8589934591 + ret i64 %and +} + +; 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 useful NIHH value (0xfffaffff_ffffffff). -define i64 @f9(i64 %a) { -; CHECK-LABEL: f9: +; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-add-01.ll b/test/CodeGen/SystemZ/atomicrmw-add-01.ll index 2e1947fcf76..2c8598ddd22 100644 --- a/test/CodeGen/SystemZ/atomicrmw-add-01.ll +++ b/test/CodeGen/SystemZ/atomicrmw-add-01.ll @@ -14,14 +14,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-add-02.ll b/test/CodeGen/SystemZ/atomicrmw-add-02.ll index 76f7c2ed6b6..2aff860bd2a 100644 --- a/test/CodeGen/SystemZ/atomicrmw-add-02.ll +++ b/test/CodeGen/SystemZ/atomicrmw-add-02.ll @@ -14,14 +14,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-and-01.ll b/test/CodeGen/SystemZ/atomicrmw-and-01.ll index 243cf1573ed..5cb5aba7923 100644 --- a/test/CodeGen/SystemZ/atomicrmw-and-01.ll +++ b/test/CodeGen/SystemZ/atomicrmw-and-01.ll @@ -14,14 +14,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-and-02.ll b/test/CodeGen/SystemZ/atomicrmw-and-02.ll index 31247a335d9..bc92db141e1 100644 --- a/test/CodeGen/SystemZ/atomicrmw-and-02.ll +++ b/test/CodeGen/SystemZ/atomicrmw-and-02.ll @@ -14,14 +14,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-and-04.ll b/test/CodeGen/SystemZ/atomicrmw-and-04.ll index b224423c0b3..649eeebe5d6 100644 --- a/test/CodeGen/SystemZ/atomicrmw-and-04.ll +++ b/test/CodeGen/SystemZ/atomicrmw-and-04.ll @@ -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 - ret i64 %res -} - -; Check the low end of the NIHH range. -define i64 @f5(i64 %dummy, i64 *%src) { -; CHECK-LABEL: f5: -; CHECK: nihh %r0, 0 -; CHECK: br %r14 - %res = atomicrmw and i64 *%src, i64 281474976710655 seq_cst + %res = atomicrmw and i64 *%src, i64 12884901887 seq_cst ret i64 %res } ; Check the next value up, which must use a register. +define i64 @f5(i64 %dummy, i64 *%src) { +; CHECK-LABEL: f5: +; CHECK: ngr +; CHECK: br %r14 + %res = atomicrmw and i64 *%src, i64 12884901888 seq_cst + ret i64 %res +} + +; Check the lowest NIHH value outside the range of RISBG. define i64 @f6(i64 %dummy, i64 *%src) { ; CHECK-LABEL: f6: +; CHECK: nihh {{%r[0-5]}}, 2 +; CHECK: br %r14 + %res = atomicrmw and i64 *%src, i64 844424930131967 seq_cst + ret i64 %res +} + +; Check the next value up, which must use a register. +define i64 @f7(i64 %dummy, i64 *%src) { +; CHECK-LABEL: f7: ; CHECK: ngr ; CHECK: br %r14 %res = atomicrmw and i64 *%src, i64 281474976710656 seq_cst ret i64 %res } -; Check the highest useful NILL value. -define i64 @f7(i64 %dummy, i64 *%src) { -; CHECK-LABEL: f7: -; CHECK: nill %r0, 65534 -; CHECK: br %r14 - %res = atomicrmw and i64 *%src, i64 -2 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-minmax-01.ll b/test/CodeGen/SystemZ/atomicrmw-minmax-01.ll index 1a9db879396..7368758f612 100644 --- a/test/CodeGen/SystemZ/atomicrmw-minmax-01.ll +++ b/test/CodeGen/SystemZ/atomicrmw-minmax-01.ll @@ -14,16 +14,16 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-minmax-02.ll b/test/CodeGen/SystemZ/atomicrmw-minmax-02.ll index 2f6d3eddc07..e5541b53268 100644 --- a/test/CodeGen/SystemZ/atomicrmw-minmax-02.ll +++ b/test/CodeGen/SystemZ/atomicrmw-minmax-02.ll @@ -14,16 +14,16 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-nand-01.ll b/test/CodeGen/SystemZ/atomicrmw-nand-01.ll index cdeeaba3c3a..ec81af21086 100644 --- a/test/CodeGen/SystemZ/atomicrmw-nand-01.ll +++ b/test/CodeGen/SystemZ/atomicrmw-nand-01.ll @@ -14,15 +14,15 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-nand-02.ll b/test/CodeGen/SystemZ/atomicrmw-nand-02.ll index 60fdbc782dd..3396f68fa79 100644 --- a/test/CodeGen/SystemZ/atomicrmw-nand-02.ll +++ b/test/CodeGen/SystemZ/atomicrmw-nand-02.ll @@ -14,15 +14,15 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-nand-04.ll b/test/CodeGen/SystemZ/atomicrmw-nand-04.ll index 907647106c8..cda7aa2673a 100644 --- a/test/CodeGen/SystemZ/atomicrmw-nand-04.ll +++ b/test/CodeGen/SystemZ/atomicrmw-nand-04.ll @@ -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: br %r14 - %res = atomicrmw nand i64 *%src, i64 4294967296 seq_cst - ret i64 %res -} - -; Check the low end of the NIHH range. -define i64 @f5(i64 %dummy, i64 *%src) { -; CHECK-LABEL: f5: -; CHECK: nihh %r0, 0 +; 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 281474976710655 seq_cst + %res = atomicrmw nand i64 *%src, i64 12884901887 seq_cst ret i64 %res } ; Check the next value up, which must use a register. +define i64 @f5(i64 %dummy, i64 *%src) { +; CHECK-LABEL: f5: +; CHECK: ngr +; CHECK: br %r14 + %res = atomicrmw nand i64 *%src, i64 12884901888 seq_cst + ret i64 %res +} + +; Check the lowest NIHH value outside the range of RISBG. define i64 @f6(i64 %dummy, i64 *%src) { ; CHECK-LABEL: f6: +; CHECK: nihh {{%r[0-5]}}, 2 +; CHECK: br %r14 + %res = atomicrmw nand i64 *%src, i64 844424930131967 seq_cst + ret i64 %res +} + +; Check the next value up, which must use a register. +define i64 @f7(i64 %dummy, i64 *%src) { +; CHECK-LABEL: f7: ; CHECK: ngr ; CHECK: br %r14 %res = atomicrmw nand i64 *%src, i64 281474976710656 seq_cst ret i64 %res } -; Check the highest useful NILL value. -define i64 @f7(i64 %dummy, i64 *%src) { -; CHECK-LABEL: f7: -; CHECK: nill %r0, 65534 -; CHECK: lcgr %r0, %r0 -; CHECK: aghi %r0, -1 -; CHECK: br %r14 - %res = atomicrmw nand i64 *%src, i64 -2 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-or-01.ll b/test/CodeGen/SystemZ/atomicrmw-or-01.ll index fe1beedce74..bf4be43e318 100644 --- a/test/CodeGen/SystemZ/atomicrmw-or-01.ll +++ b/test/CodeGen/SystemZ/atomicrmw-or-01.ll @@ -14,14 +14,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-or-02.ll b/test/CodeGen/SystemZ/atomicrmw-or-02.ll index 73bc2826444..726d9aaa35c 100644 --- a/test/CodeGen/SystemZ/atomicrmw-or-02.ll +++ b/test/CodeGen/SystemZ/atomicrmw-or-02.ll @@ -14,14 +14,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-sub-01.ll b/test/CodeGen/SystemZ/atomicrmw-sub-01.ll index e1060e05517..6d42545631e 100644 --- a/test/CodeGen/SystemZ/atomicrmw-sub-01.ll +++ b/test/CodeGen/SystemZ/atomicrmw-sub-01.ll @@ -14,14 +14,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-sub-02.ll b/test/CodeGen/SystemZ/atomicrmw-sub-02.ll index 499a606f0b6..6f8e26e5c08 100644 --- a/test/CodeGen/SystemZ/atomicrmw-sub-02.ll +++ b/test/CodeGen/SystemZ/atomicrmw-sub-02.ll @@ -14,14 +14,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-xchg-01.ll b/test/CodeGen/SystemZ/atomicrmw-xchg-01.ll index d83408f2588..238ce336ac4 100644 --- a/test/CodeGen/SystemZ/atomicrmw-xchg-01.ll +++ b/test/CodeGen/SystemZ/atomicrmw-xchg-01.ll @@ -12,14 +12,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-xchg-02.ll b/test/CodeGen/SystemZ/atomicrmw-xchg-02.ll index b00b341d4fc..635d9d440d2 100644 --- a/test/CodeGen/SystemZ/atomicrmw-xchg-02.ll +++ b/test/CodeGen/SystemZ/atomicrmw-xchg-02.ll @@ -12,14 +12,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-xor-01.ll b/test/CodeGen/SystemZ/atomicrmw-xor-01.ll index b457a608732..969e3ef87c4 100644 --- a/test/CodeGen/SystemZ/atomicrmw-xor-01.ll +++ b/test/CodeGen/SystemZ/atomicrmw-xor-01.ll @@ -14,14 +14,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/atomicrmw-xor-02.ll b/test/CodeGen/SystemZ/atomicrmw-xor-02.ll index fa38d7027f5..10d2e3f592b 100644 --- a/test/CodeGen/SystemZ/atomicrmw-xor-02.ll +++ b/test/CodeGen/SystemZ/atomicrmw-xor-02.ll @@ -14,14 +14,14 @@ ; 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 diff --git a/test/CodeGen/SystemZ/cmpxchg-01.ll b/test/CodeGen/SystemZ/cmpxchg-01.ll index c6f10380c2f..467fe68be3e 100644 --- a/test/CodeGen/SystemZ/cmpxchg-01.ll +++ b/test/CodeGen/SystemZ/cmpxchg-01.ll @@ -12,16 +12,16 @@ ; 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 diff --git a/test/CodeGen/SystemZ/cmpxchg-02.ll b/test/CodeGen/SystemZ/cmpxchg-02.ll index fa2d088295b..c7ee898ce27 100644 --- a/test/CodeGen/SystemZ/cmpxchg-02.ll +++ b/test/CodeGen/SystemZ/cmpxchg-02.ll @@ -12,16 +12,16 @@ ; 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 diff --git a/test/CodeGen/SystemZ/fp-move-02.ll b/test/CodeGen/SystemZ/fp-move-02.ll index b6fc0d58337..b4f042859a0 100644 --- a/test/CodeGen/SystemZ/fp-move-02.ll +++ b/test/CodeGen/SystemZ/fp-move-02.ll @@ -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 diff --git a/test/CodeGen/SystemZ/insert-01.ll b/test/CodeGen/SystemZ/insert-01.ll index 5f14b2919e1..0b54e85dc4e 100644 --- a/test/CodeGen/SystemZ/insert-01.ll +++ b/test/CodeGen/SystemZ/insert-01.ll @@ -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 diff --git a/test/CodeGen/SystemZ/insert-02.ll b/test/CodeGen/SystemZ/insert-02.ll index 05958a65dc2..7a85b0bee4d 100644 --- a/test/CodeGen/SystemZ/insert-02.ll +++ b/test/CodeGen/SystemZ/insert-02.ll @@ -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 diff --git a/test/CodeGen/SystemZ/risbg-01.ll b/test/CodeGen/SystemZ/risbg-01.ll index 6f89fefd9fe..85de6dc6af2 100644 --- a/test/CodeGen/SystemZ/risbg-01.ll +++ b/test/CodeGen/SystemZ/risbg-01.ll @@ -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