From: Richard Sandiford Date: Wed, 31 Jul 2013 11:36:35 +0000 (+0000) Subject: [SystemZ] Postpone NI->RISBG conversion to convertToThreeAddress() X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=b3f912b510f8040690864126351b7021980558bb;p=oota-llvm.git [SystemZ] Postpone NI->RISBG conversion to convertToThreeAddress() 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 --- 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)) { - 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(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; - - // 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) { 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>; + 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>, 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,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 } 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: 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 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 + %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 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: 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 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