mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
[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
This commit is contained in:
parent
5d7e93c0d4
commit
d1a4f579bf
@ -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;
|
||||
|
@ -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<CondCodeSDNode>(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<CondCodeSDNode>(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<GlobalAddressSDNode>(Op), DAG);
|
||||
case ISD::GlobalTLSAddress:
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
73
test/CodeGen/SystemZ/setcc-01.ll
Normal file
73
test/CodeGen/SystemZ/setcc-01.ll
Normal file
@ -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
|
||||
}
|
173
test/CodeGen/SystemZ/setcc-02.ll
Normal file
173
test/CodeGen/SystemZ/setcc-02.ll
Normal file
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user