From d1a4f579bf45aec933c79292b6b9663581438738 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 16 Oct 2013 11:10:55 +0000 Subject: [SystemZ] Improve handling of SETCC We previously used the default expansion to SELECT_CC, which in turn would expand to "LHI; BRC; LHI". In most cases it's better to use an IPM-based sequence instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192784 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SystemZ/SystemZ.h | 3 + lib/Target/SystemZ/SystemZISelLowering.cpp | 116 ++++++++++++++++- lib/Target/SystemZ/SystemZISelLowering.h | 1 + lib/Target/SystemZ/SystemZInstrInfo.cpp | 2 +- lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp | 2 +- test/CodeGen/SystemZ/branch-07.ll | 30 ++--- test/CodeGen/SystemZ/setcc-01.ll | 73 +++++++++++ test/CodeGen/SystemZ/setcc-02.ll | 173 +++++++++++++++++++++++++ 8 files changed, 380 insertions(+), 20 deletions(-) create mode 100644 test/CodeGen/SystemZ/setcc-01.ll create mode 100644 test/CodeGen/SystemZ/setcc-02.ll diff --git a/lib/Target/SystemZ/SystemZ.h b/lib/Target/SystemZ/SystemZ.h index 4a6b4db9d6..dcebbad590 100644 --- a/lib/Target/SystemZ/SystemZ.h +++ b/lib/Target/SystemZ/SystemZ.h @@ -68,6 +68,9 @@ namespace llvm { const unsigned CCMASK_TM_MSB_1 = CCMASK_2 | CCMASK_3; const unsigned CCMASK_TM = CCMASK_ANY; + // The position of the low CC bit in an IPM result. + const unsigned IPM_CC = 28; + // Mask assignments for PFD. const unsigned PFD_READ = 1; const unsigned PFD_WRITE = 2; diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index b1ec331c3e..380ce62363 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -27,6 +27,19 @@ using namespace llvm; +namespace { +// Represents a sequence for extracting a 0/1 value from an IPM result: +// (((X ^ XORValue) + AddValue) >> Bit) +struct IPMConversion { + IPMConversion(unsigned xorValue, int64_t addValue, unsigned bit) + : XORValue(xorValue), AddValue(addValue), Bit(bit) {} + + int64_t XORValue; + int64_t AddValue; + unsigned Bit; +}; +} + // Classify VT as either 32 or 64 bit. static bool is32Bit(EVT VT) { switch (VT.getSimpleVT().SimpleTy) { @@ -88,8 +101,8 @@ SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) ++I) { MVT VT = MVT::SimpleValueType(I); if (isTypeLegal(VT)) { - // Expand SETCC(X, Y, COND) into SELECT_CC(X, Y, 1, 0, COND). - setOperationAction(ISD::SETCC, VT, Expand); + // Lower SET_CC into an IPM-based sequence. + setOperationAction(ISD::SETCC, VT, Custom); // Expand SELECT(C, A, B) into SELECT_CC(X, 0, A, B, NE). setOperationAction(ISD::SELECT, VT, Expand); @@ -980,6 +993,73 @@ static unsigned CCMaskForCondCode(ISD::CondCode CC) { #undef CONV } +// Return a sequence for getting a 1 from an IPM result when CC has a +// value in CCMask and a 0 when CC has a value in CCValid & ~CCMask. +// The handling of CC values outside CCValid doesn't matter. +static IPMConversion getIPMConversion(unsigned CCValid, unsigned CCMask) { + // Deal with cases where the result can be taken directly from a bit + // of the IPM result. + if (CCMask == (CCValid & (SystemZ::CCMASK_1 | SystemZ::CCMASK_3))) + return IPMConversion(0, 0, SystemZ::IPM_CC); + if (CCMask == (CCValid & (SystemZ::CCMASK_2 | SystemZ::CCMASK_3))) + return IPMConversion(0, 0, SystemZ::IPM_CC + 1); + + // Deal with cases where we can add a value to force the sign bit + // to contain the right value. Putting the bit in 31 means we can + // use SRL rather than RISBG(L), and also makes it easier to get a + // 0/-1 value, so it has priority over the other tests below. + // + // These sequences rely on the fact that the upper two bits of the + // IPM result are zero. + uint64_t TopBit = uint64_t(1) << 31; + if (CCMask == (CCValid & SystemZ::CCMASK_0)) + return IPMConversion(0, -(1 << SystemZ::IPM_CC), 31); + if (CCMask == (CCValid & (SystemZ::CCMASK_0 | SystemZ::CCMASK_1))) + return IPMConversion(0, -(2 << SystemZ::IPM_CC), 31); + if (CCMask == (CCValid & (SystemZ::CCMASK_0 + | SystemZ::CCMASK_1 + | SystemZ::CCMASK_2))) + return IPMConversion(0, -(3 << SystemZ::IPM_CC), 31); + if (CCMask == (CCValid & SystemZ::CCMASK_3)) + return IPMConversion(0, TopBit - (3 << SystemZ::IPM_CC), 31); + if (CCMask == (CCValid & (SystemZ::CCMASK_1 + | SystemZ::CCMASK_2 + | SystemZ::CCMASK_3))) + return IPMConversion(0, TopBit - (1 << SystemZ::IPM_CC), 31); + + // Next try inverting the value and testing a bit. 0/1 could be + // handled this way too, but we dealt with that case above. + if (CCMask == (CCValid & (SystemZ::CCMASK_0 | SystemZ::CCMASK_2))) + return IPMConversion(-1, 0, SystemZ::IPM_CC); + + // Handle cases where adding a value forces a non-sign bit to contain + // the right value. + if (CCMask == (CCValid & (SystemZ::CCMASK_1 | SystemZ::CCMASK_2))) + return IPMConversion(0, 1 << SystemZ::IPM_CC, SystemZ::IPM_CC + 1); + if (CCMask == (CCValid & (SystemZ::CCMASK_0 | SystemZ::CCMASK_3))) + return IPMConversion(0, -(1 << SystemZ::IPM_CC), SystemZ::IPM_CC + 1); + + // The remaing cases are 1, 2, 0/1/3 and 0/2/3. All these are + // can be done by inverting the low CC bit and applying one of the + // sign-based extractions above. + if (CCMask == (CCValid & SystemZ::CCMASK_1)) + return IPMConversion(1 << SystemZ::IPM_CC, -(1 << SystemZ::IPM_CC), 31); + if (CCMask == (CCValid & SystemZ::CCMASK_2)) + return IPMConversion(1 << SystemZ::IPM_CC, + TopBit - (3 << SystemZ::IPM_CC), 31); + if (CCMask == (CCValid & (SystemZ::CCMASK_0 + | SystemZ::CCMASK_1 + | SystemZ::CCMASK_3))) + return IPMConversion(1 << SystemZ::IPM_CC, -(3 << SystemZ::IPM_CC), 31); + if (CCMask == (CCValid & (SystemZ::CCMASK_0 + | SystemZ::CCMASK_2 + | SystemZ::CCMASK_3))) + return IPMConversion(1 << SystemZ::IPM_CC, + TopBit - (1 << SystemZ::IPM_CC), 31); + + llvm_unreachable("Unexpected CC combination"); +} + // If a comparison described by IsUnsigned, CCMask, CmpOp0 and CmpOp1 // can be converted to a comparison against zero, adjust the operands // as necessary. @@ -1401,6 +1481,36 @@ static void lowerGR128Binary(SelectionDAG &DAG, SDLoc DL, EVT VT, Odd = DAG.getTargetExtractSubreg(SystemZ::odd128(Is32Bit), DL, VT, Result); } +SDValue SystemZTargetLowering::lowerSETCC(SDValue Op, + SelectionDAG &DAG) const { + SDValue CmpOp0 = Op.getOperand(0); + SDValue CmpOp1 = Op.getOperand(1); + ISD::CondCode CC = cast(Op.getOperand(2))->get(); + SDLoc DL(Op); + + unsigned CCValid, CCMask; + SDValue Glue = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask); + + IPMConversion Conversion = getIPMConversion(CCValid, CCMask); + SDValue Result = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, Glue); + + if (Conversion.XORValue) + Result = DAG.getNode(ISD::XOR, DL, MVT::i32, Result, + DAG.getConstant(Conversion.XORValue, MVT::i32)); + + if (Conversion.AddValue) + Result = DAG.getNode(ISD::ADD, DL, MVT::i32, Result, + DAG.getConstant(Conversion.AddValue, MVT::i32)); + + // The SHR/AND sequence should get optimized to an RISBG. + Result = DAG.getNode(ISD::SRL, DL, MVT::i32, Result, + DAG.getConstant(Conversion.Bit, MVT::i32)); + if (Conversion.Bit != 31) + Result = DAG.getNode(ISD::AND, DL, MVT::i32, Result, + DAG.getConstant(1, MVT::i32)); + return Result; +} + SDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); ISD::CondCode CC = cast(Op.getOperand(1))->get(); @@ -1997,6 +2107,8 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op, return lowerBR_CC(Op, DAG); case ISD::SELECT_CC: return lowerSELECT_CC(Op, DAG); + case ISD::SETCC: + return lowerSETCC(Op, DAG); case ISD::GlobalAddress: return lowerGlobalAddress(cast(Op), DAG); case ISD::GlobalTLSAddress: diff --git a/lib/Target/SystemZ/SystemZISelLowering.h b/lib/Target/SystemZ/SystemZISelLowering.h index 3f272c3856..820b680382 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.h +++ b/lib/Target/SystemZ/SystemZISelLowering.h @@ -252,6 +252,7 @@ private: const SystemZTargetMachine &TM; // Implement LowerOperation for individual opcodes. + SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const; SDValue lowerBR_CC(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; SDValue lowerGlobalAddress(GlobalAddressSDNode *Node, diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index 83e023f002..2ebbc0d81a 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -449,7 +449,7 @@ static bool removeIPMBasedCompare(MachineInstr *Compare, unsigned SrcReg, return false; MachineInstr *SRL = getDef(RLL->getOperand(1).getReg(), MRI); - if (!SRL || !isShift(SRL, SystemZ::SRL, 28)) + if (!SRL || !isShift(SRL, SystemZ::SRL, SystemZ::IPM_CC)) return false; MachineInstr *IPM = getDef(SRL->getOperand(1).getReg(), MRI); diff --git a/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp b/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp index 3b43cbdb3e..c7ebb5d6b4 100644 --- a/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp +++ b/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp @@ -183,7 +183,7 @@ static SDValue emitCLC(SelectionDAG &DAG, SDLoc DL, SDValue Chain, static SDValue addIPMSequence(SDLoc DL, SDValue Glue, SelectionDAG &DAG) { SDValue IPM = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, Glue); SDValue SRL = DAG.getNode(ISD::SRL, DL, MVT::i32, IPM, - DAG.getConstant(28, MVT::i32)); + DAG.getConstant(SystemZ::IPM_CC, MVT::i32)); SDValue ROTL = DAG.getNode(ISD::ROTL, DL, MVT::i32, SRL, DAG.getConstant(31, MVT::i32)); return ROTL; diff --git a/test/CodeGen/SystemZ/branch-07.ll b/test/CodeGen/SystemZ/branch-07.ll index b715a059bc..bac607133a 100644 --- a/test/CodeGen/SystemZ/branch-07.ll +++ b/test/CodeGen/SystemZ/branch-07.ll @@ -97,10 +97,9 @@ exit: ; Test a vector of 0/-1 results for i32 EQ. define i64 @f7(i64 %a, i64 %b) { ; CHECK-LABEL: f7: -; CHECK: lhi [[REG:%r[0-5]]], -1 -; CHECK: crje {{%r[0-5]}} -; CHECK: lhi [[REG]], 0 -; CHECK-NOT: sra +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK: afi [[REG]], -268435456 +; CHECK: sra [[REG]], 31 ; CHECK: br %r14 %avec = bitcast i64 %a to <2 x i32> %bvec = bitcast i64 %b to <2 x i32> @@ -113,10 +112,9 @@ define i64 @f7(i64 %a, i64 %b) { ; Test a vector of 0/-1 results for i32 NE. define i64 @f8(i64 %a, i64 %b) { ; CHECK-LABEL: f8: -; CHECK: lhi [[REG:%r[0-5]]], -1 -; CHECK: crjlh {{%r[0-5]}} -; CHECK: lhi [[REG]], 0 -; CHECK-NOT: sra +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK: afi [[REG]], 1879048192 +; CHECK: sra [[REG]], 31 ; CHECK: br %r14 %avec = bitcast i64 %a to <2 x i32> %bvec = bitcast i64 %b to <2 x i32> @@ -129,10 +127,10 @@ define i64 @f8(i64 %a, i64 %b) { ; Test a vector of 0/-1 results for i64 EQ. define void @f9(i64 %a, i64 %b, <2 x i64> *%dest) { ; CHECK-LABEL: f9: -; CHECK: lghi [[REG:%r[0-5]]], -1 -; CHECK: crje {{%r[0-5]}} -; CHECK: lghi [[REG]], 0 -; CHECK-NOT: sra +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK: afi [[REG]], -268435456 +; CHECK: sllg [[REG2:%r[0-5]]], [[REG]], 32 +; CHECK: srag {{%r[0-5]}}, [[REG2]], 63 ; CHECK: br %r14 %avec = bitcast i64 %a to <2 x i32> %bvec = bitcast i64 %b to <2 x i32> @@ -145,10 +143,10 @@ define void @f9(i64 %a, i64 %b, <2 x i64> *%dest) { ; Test a vector of 0/-1 results for i64 NE. define void @f10(i64 %a, i64 %b, <2 x i64> *%dest) { ; CHECK-LABEL: f10: -; CHECK: lghi [[REG:%r[0-5]]], -1 -; CHECK: crjlh {{%r[0-5]}} -; CHECK: lghi [[REG]], 0 -; CHECK-NOT: sra +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK: afi [[REG]], 1879048192 +; CHECK: sllg [[REG2:%r[0-5]]], [[REG]], 32 +; CHECK: srag {{%r[0-5]}}, [[REG2]], 63 ; CHECK: br %r14 %avec = bitcast i64 %a to <2 x i32> %bvec = bitcast i64 %b to <2 x i32> diff --git a/test/CodeGen/SystemZ/setcc-01.ll b/test/CodeGen/SystemZ/setcc-01.ll new file mode 100644 index 0000000000..5313215f11 --- /dev/null +++ b/test/CodeGen/SystemZ/setcc-01.ll @@ -0,0 +1,73 @@ +; Test SETCC for every integer condition. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +; Test CC in { 0 }, with 3 don't care. +define i32 @f1(i32 %a, i32 %b) { +; CHECK-LABEL: f1: +; CHECK: ipm %r2 +; CHECK-NEXT: afi %r2, -268435456 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = icmp eq i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 1 }, with 3 don't care. +define i32 @f2(i32 %a, i32 %b) { +; CHECK-LABEL: f2: +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK-NEXT: risbg %r2, [[REG]], 63, 191, 36 +; CHECK: br %r14 + %cond = icmp slt i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 0, 1 }, with 3 don't care. +define i32 @f3(i32 %a, i32 %b) { +; CHECK-LABEL: f3: +; CHECK: ipm %r2 +; CHECK-NEXT: afi %r2, -536870912 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = icmp sle i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 2 }, with 3 don't care. +define i32 @f4(i32 %a, i32 %b) { +; CHECK-LABEL: f4: +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK-NEXT: risbg %r2, [[REG]], 63, 191, 35 +; CHECK: br %r14 + %cond = icmp sgt i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 0, 2 }, with 3 don't care. +define i32 @f5(i32 %a, i32 %b) { +; CHECK-LABEL: f5: +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK-NEXT: xilf [[REG]], 4294967295 +; CHECK-NEXT: risbg %r2, [[REG]], 63, 191, 36 +; CHECK: br %r14 + %cond = icmp sge i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 1, 2 }, with 3 don't care. +define i32 @f6(i32 %a, i32 %b) { +; CHECK-LABEL: f6: +; CHECK: ipm %r2 +; CHECK-NEXT: afi %r2, 1879048192 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = icmp ne i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} diff --git a/test/CodeGen/SystemZ/setcc-02.ll b/test/CodeGen/SystemZ/setcc-02.ll new file mode 100644 index 0000000000..178822277d --- /dev/null +++ b/test/CodeGen/SystemZ/setcc-02.ll @@ -0,0 +1,173 @@ +; Test SETCC for every floating-point condition. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +; Test CC in { 0 } +define i32 @f1(float %a, float %b) { +; CHECK-LABEL: f1: +; CHECK: ipm %r2 +; CHECK-NEXT: afi %r2, -268435456 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = fcmp oeq float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 1 } +define i32 @f2(float %a, float %b) { +; CHECK-LABEL: f2: +; CHECK: ipm %r2 +; CHECK-NEXT: xilf %r2, 268435456 +; CHECK-NEXT: afi %r2, -268435456 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = fcmp olt float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 0, 1 } +define i32 @f3(float %a, float %b) { +; CHECK-LABEL: f3: +; CHECK: ipm %r2 +; CHECK-NEXT: afi %r2, -536870912 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = fcmp ole float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 2 } +define i32 @f4(float %a, float %b) { +; CHECK-LABEL: f4: +; CHECK: ipm %r2 +; CHECK-NEXT: xilf %r2, 268435456 +; CHECK-NEXT: afi %r2, 1342177280 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = fcmp ogt float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 0, 2 } +define i32 @f5(float %a, float %b) { +; CHECK-LABEL: f5: +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK-NEXT: xilf [[REG]], 4294967295 +; CHECK-NEXT: risbg %r2, [[REG]], 63, 191, 36 +; CHECK: br %r14 + %cond = fcmp oge float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 1, 2 } +define i32 @f6(float %a, float %b) { +; CHECK-LABEL: f6: +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK-NEXT: afi [[REG]], 268435456 +; CHECK-NEXT: risbg %r2, [[REG]], 63, 191, 35 +; CHECK: br %r14 + %cond = fcmp one float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 0, 1, 2 } +define i32 @f7(float %a, float %b) { +; CHECK-LABEL: f7: +; CHECK: ipm %r2 +; CHECK-NEXT: afi %r2, -805306368 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = fcmp ord float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 3 } +define i32 @f8(float %a, float %b) { +; CHECK-LABEL: f8: +; CHECK: ipm %r2 +; CHECK-NEXT: afi %r2, 1342177280 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = fcmp uno float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 0, 3 } +define i32 @f9(float %a, float %b) { +; CHECK-LABEL: f9: +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK-NEXT: afi [[REG]], -268435456 +; CHECK-NEXT: risbg %r2, [[REG]], 63, 191, 35 +; CHECK: br %r14 + %cond = fcmp ueq float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 1, 3 } +define i32 @f10(float %a, float %b) { +; CHECK-LABEL: f10: +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK-NEXT: risbg %r2, [[REG]], 63, 191, 36 +; CHECK: br %r14 + %cond = fcmp ult float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 0, 1, 3 } +define i32 @f11(float %a, float %b) { +; CHECK-LABEL: f11: +; CHECK: ipm %r2 +; CHECK-NEXT: xilf %r2, 268435456 +; CHECK-NEXT: afi %r2, -805306368 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = fcmp ule float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 2, 3 } +define i32 @f12(float %a, float %b) { +; CHECK-LABEL: f12: +; CHECK: ipm [[REG:%r[0-5]]] +; CHECK-NEXT: risbg %r2, [[REG]], 63, 191, 35 +; CHECK: br %r14 + %cond = fcmp ugt float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 0, 2, 3 } +define i32 @f13(float %a, float %b) { +; CHECK-LABEL: f13: +; CHECK: ipm %r2 +; CHECK-NEXT: xilf %r2, 268435456 +; CHECK-NEXT: afi %r2, 1879048192 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = fcmp uge float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +; Test CC in { 1, 2, 3 } +define i32 @f14(float %a, float %b) { +; CHECK-LABEL: f14: +; CHECK: ipm %r2 +; CHECK-NEXT: afi %r2, 1879048192 +; CHECK-NEXT: srl %r2, 31 +; CHECK: br %r14 + %cond = fcmp une float %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} -- cgit v1.2.3