mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 02:29:18 +00:00
[SystemZ] Optimize selects between 0 and -1
Since z has no setcc instruction as such, the choice of setBooleanContents is a bit arbitrary. Currently it's set to ZeroOrOneBooleanContent, so we produced a branch-free form when selecting between 0 and 1, but not when selecting between 0 and -1. This patch handles the latter case too. At some point I'd like to measure whether it's better to use conditional moves for constant selects on z196, but that's future work. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196578 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5aafde2d5a
commit
e3a804ba21
@ -1486,16 +1486,11 @@ static void lowerGR128Binary(SelectionDAG &DAG, SDLoc DL, EVT VT,
|
|||||||
Odd = DAG.getTargetExtractSubreg(SystemZ::odd128(Is32Bit), DL, VT, Result);
|
Odd = DAG.getTargetExtractSubreg(SystemZ::odd128(Is32Bit), DL, VT, Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue SystemZTargetLowering::lowerSETCC(SDValue Op,
|
// Return an i32 value that is 1 if the CC value produced by Glue is
|
||||||
SelectionDAG &DAG) const {
|
// in the mask CCMask and 0 otherwise. CC is known to have a value
|
||||||
SDValue CmpOp0 = Op.getOperand(0);
|
// in CCValid, so other values can be ignored.
|
||||||
SDValue CmpOp1 = Op.getOperand(1);
|
static SDValue emitSETCC(SelectionDAG &DAG, SDLoc DL, SDValue Glue,
|
||||||
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
|
unsigned CCValid, unsigned CCMask) {
|
||||||
SDLoc DL(Op);
|
|
||||||
|
|
||||||
unsigned CCValid, CCMask;
|
|
||||||
SDValue Glue = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask);
|
|
||||||
|
|
||||||
IPMConversion Conversion = getIPMConversion(CCValid, CCMask);
|
IPMConversion Conversion = getIPMConversion(CCValid, CCMask);
|
||||||
SDValue Result = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, Glue);
|
SDValue Result = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, Glue);
|
||||||
|
|
||||||
@ -1516,6 +1511,18 @@ SDValue SystemZTargetLowering::lowerSETCC(SDValue Op,
|
|||||||
return Result;
|
return 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);
|
||||||
|
return emitSETCC(DAG, DL, Glue, CCValid, CCMask);
|
||||||
|
}
|
||||||
|
|
||||||
SDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
|
SDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
|
||||||
SDValue Chain = Op.getOperand(0);
|
SDValue Chain = Op.getOperand(0);
|
||||||
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
|
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
|
||||||
@ -1525,10 +1532,10 @@ SDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
SDLoc DL(Op);
|
SDLoc DL(Op);
|
||||||
|
|
||||||
unsigned CCValid, CCMask;
|
unsigned CCValid, CCMask;
|
||||||
SDValue Flags = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask);
|
SDValue Glue = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask);
|
||||||
return DAG.getNode(SystemZISD::BR_CCMASK, DL, Op.getValueType(),
|
return DAG.getNode(SystemZISD::BR_CCMASK, DL, Op.getValueType(),
|
||||||
Chain, DAG.getConstant(CCValid, MVT::i32),
|
Chain, DAG.getConstant(CCValid, MVT::i32),
|
||||||
DAG.getConstant(CCMask, MVT::i32), Dest, Flags);
|
DAG.getConstant(CCMask, MVT::i32), Dest, Glue);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue SystemZTargetLowering::lowerSELECT_CC(SDValue Op,
|
SDValue SystemZTargetLowering::lowerSELECT_CC(SDValue Op,
|
||||||
@ -1541,14 +1548,37 @@ SDValue SystemZTargetLowering::lowerSELECT_CC(SDValue Op,
|
|||||||
SDLoc DL(Op);
|
SDLoc DL(Op);
|
||||||
|
|
||||||
unsigned CCValid, CCMask;
|
unsigned CCValid, CCMask;
|
||||||
SDValue Flags = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask);
|
SDValue Glue = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask);
|
||||||
|
|
||||||
|
// Special case for handling -1/0 results. The shifts we use here
|
||||||
|
// should get optimized with the IPM conversion sequence.
|
||||||
|
ConstantSDNode *TrueC = dyn_cast<ConstantSDNode>(TrueOp);
|
||||||
|
ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(FalseOp);
|
||||||
|
if (TrueC && FalseC) {
|
||||||
|
int64_t TrueVal = TrueC->getSExtValue();
|
||||||
|
int64_t FalseVal = FalseC->getSExtValue();
|
||||||
|
if ((TrueVal == -1 && FalseVal == 0) || (TrueVal == 0 && FalseVal == -1)) {
|
||||||
|
// Invert the condition if we want -1 on false.
|
||||||
|
if (TrueVal == 0)
|
||||||
|
CCMask ^= CCValid;
|
||||||
|
SDValue Result = emitSETCC(DAG, DL, Glue, CCValid, CCMask);
|
||||||
|
EVT VT = Op.getValueType();
|
||||||
|
// Extend the result to VT. Upper bits are ignored.
|
||||||
|
if (!is32Bit(VT))
|
||||||
|
Result = DAG.getNode(ISD::ANY_EXTEND, DL, VT, Result);
|
||||||
|
// Sign-extend from the low bit.
|
||||||
|
SDValue ShAmt = DAG.getConstant(VT.getSizeInBits() - 1, MVT::i32);
|
||||||
|
SDValue Shl = DAG.getNode(ISD::SHL, DL, VT, Result, ShAmt);
|
||||||
|
return DAG.getNode(ISD::SRA, DL, VT, Shl, ShAmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SmallVector<SDValue, 5> Ops;
|
SmallVector<SDValue, 5> Ops;
|
||||||
Ops.push_back(TrueOp);
|
Ops.push_back(TrueOp);
|
||||||
Ops.push_back(FalseOp);
|
Ops.push_back(FalseOp);
|
||||||
Ops.push_back(DAG.getConstant(CCValid, MVT::i32));
|
Ops.push_back(DAG.getConstant(CCValid, MVT::i32));
|
||||||
Ops.push_back(DAG.getConstant(CCMask, MVT::i32));
|
Ops.push_back(DAG.getConstant(CCMask, MVT::i32));
|
||||||
Ops.push_back(Flags);
|
Ops.push_back(Glue);
|
||||||
|
|
||||||
SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
|
SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
|
||||||
return DAG.getNode(SystemZISD::SELECT_CCMASK, DL, VTs, &Ops[0], Ops.size());
|
return DAG.getNode(SystemZISD::SELECT_CCMASK, DL, VTs, &Ops[0], Ops.size());
|
||||||
|
178
test/CodeGen/SystemZ/selectcc-01.ll
Normal file
178
test/CodeGen/SystemZ/selectcc-01.ll
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
; Test an i32 0/-1 SELECTCCC 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: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp oeq float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
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: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp olt float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
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: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ole float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
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: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ogt float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 2 }
|
||||||
|
define i32 @f5(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f5:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: xilf %r2, 4294967295
|
||||||
|
; CHECK-NEXT: sll %r2, 3
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp oge float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 1, 2 }
|
||||||
|
define i32 @f6(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f6:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: afi %r2, 268435456
|
||||||
|
; CHECK-NEXT: sll %r2, 2
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp one float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
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: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ord float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
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: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp uno float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 3 }
|
||||||
|
define i32 @f9(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f9:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: afi %r2, -268435456
|
||||||
|
; CHECK-NEXT: sll %r2, 2
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ueq float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 1, 3 }
|
||||||
|
define i32 @f10(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f10:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: sll %r2, 3
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ult float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
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: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ule float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 2, 3 }
|
||||||
|
define i32 @f12(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f12:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: sll %r2, 2
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ugt float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
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: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp uge float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
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: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp une float %a, %b
|
||||||
|
%res = select i1 %cond, i32 -1, i32 0
|
||||||
|
ret i32 %res
|
||||||
|
}
|
178
test/CodeGen/SystemZ/selectcc-02.ll
Normal file
178
test/CodeGen/SystemZ/selectcc-02.ll
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
; Test an i32 0/-1 SELECTCCC for every floating-point condition.
|
||||||
|
;
|
||||||
|
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
|
||||||
|
|
||||||
|
; Test CC in { 1, 2, 3 }
|
||||||
|
define i32 @f1(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f1:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: afi %r2, 1879048192
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp oeq float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 2, 3 }
|
||||||
|
define i32 @f2(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f2:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: xilf %r2, 268435456
|
||||||
|
; CHECK-NEXT: afi %r2, 1879048192
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp olt float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 2, 3 }
|
||||||
|
define i32 @f3(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f3:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: sll %r2, 2
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ole float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 1, 3 }
|
||||||
|
define i32 @f4(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f4:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: xilf %r2, 268435456
|
||||||
|
; CHECK-NEXT: afi %r2, -805306368
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ogt float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 1, 3 }
|
||||||
|
define i32 @f5(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f5:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: sll %r2, 3
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp oge float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 3 }
|
||||||
|
define i32 @f6(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f6:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: afi %r2, -268435456
|
||||||
|
; CHECK-NEXT: sll %r2, 2
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp one float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 3 }
|
||||||
|
define i32 @f7(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f7:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: afi %r2, 1342177280
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ord float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 1, 2 }
|
||||||
|
define i32 @f8(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f8:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: afi %r2, -805306368
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp uno float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 1, 2 }
|
||||||
|
define i32 @f9(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f9:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: afi %r2, 268435456
|
||||||
|
; CHECK-NEXT: sll %r2, 2
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ueq float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 2 }
|
||||||
|
define i32 @f10(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f10:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: xilf %r2, 4294967295
|
||||||
|
; CHECK-NEXT: sll %r2, 3
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ult float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 2 }
|
||||||
|
define i32 @f11(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f11:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: xilf %r2, 268435456
|
||||||
|
; CHECK-NEXT: afi %r2, 1342177280
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ule float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 1 }
|
||||||
|
define i32 @f12(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f12:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: afi %r2, -536870912
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ugt float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 1 }
|
||||||
|
define i32 @f13(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f13:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: xilf %r2, 268435456
|
||||||
|
; CHECK-NEXT: afi %r2, -268435456
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp uge float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0 }
|
||||||
|
define i32 @f14(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f14:
|
||||||
|
; CHECK: ipm %r2
|
||||||
|
; CHECK-NEXT: afi %r2, -268435456
|
||||||
|
; CHECK-NEXT: sra %r2, 31
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp une float %a, %b
|
||||||
|
%res = select i1 %cond, i32 0, i32 -1
|
||||||
|
ret i32 %res
|
||||||
|
}
|
187
test/CodeGen/SystemZ/selectcc-03.ll
Normal file
187
test/CodeGen/SystemZ/selectcc-03.ll
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
; Test an i64 0/-1 SELECTCCC for every floating-point condition.
|
||||||
|
;
|
||||||
|
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
|
||||||
|
|
||||||
|
; Test CC in { 0 }
|
||||||
|
define i64 @f1(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f1:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: afi [[REG]], -268435456
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 32
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp oeq float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 1 }
|
||||||
|
define i64 @f2(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f2:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: xilf [[REG]], 268435456
|
||||||
|
; CHECK-NEXT: afi [[REG]], -268435456
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 32
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp olt float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 1 }
|
||||||
|
define i64 @f3(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f3:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: afi [[REG]], -536870912
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 32
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ole float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 2 }
|
||||||
|
define i64 @f4(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f4:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: xilf [[REG]], 268435456
|
||||||
|
; CHECK-NEXT: afi [[REG]], 1342177280
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 32
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ogt float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 2 }
|
||||||
|
define i64 @f5(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f5:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: xilf [[REG]], 4294967295
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 35
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp oge float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 1, 2 }
|
||||||
|
define i64 @f6(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f6:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: afi [[REG]], 268435456
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 34
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp one float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 1, 2 }
|
||||||
|
define i64 @f7(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f7:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: afi [[REG]], -805306368
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 32
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ord float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 3 }
|
||||||
|
define i64 @f8(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f8:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: afi [[REG]], 1342177280
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 32
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp uno float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 3 }
|
||||||
|
define i64 @f9(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f9:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: afi [[REG]], -268435456
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 34
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ueq float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 1, 3 }
|
||||||
|
define i64 @f10(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f10:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 35
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ult float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 1, 3 }
|
||||||
|
define i64 @f11(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f11:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: xilf [[REG]], 268435456
|
||||||
|
; CHECK-NEXT: afi [[REG]], -805306368
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 32
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ule float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 2, 3 }
|
||||||
|
define i64 @f12(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f12:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 34
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp ugt float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 0, 2, 3 }
|
||||||
|
define i64 @f13(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f13:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: xilf [[REG]], 268435456
|
||||||
|
; CHECK-NEXT: afi [[REG]], 1879048192
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 32
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp uge float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test CC in { 1, 2, 3 }
|
||||||
|
define i64 @f14(float %a, float %b) {
|
||||||
|
; CHECK-LABEL: f14:
|
||||||
|
; CHECK: ipm [[REG:%r[0-5]]]
|
||||||
|
; CHECK-NEXT: afi [[REG]], 1879048192
|
||||||
|
; CHECK-NEXT: sllg [[REG]], [[REG]], 32
|
||||||
|
; CHECK-NEXT: srag %r2, [[REG]], 63
|
||||||
|
; CHECK: br %r14
|
||||||
|
%cond = fcmp une float %a, %b
|
||||||
|
%res = select i1 %cond, i64 -1, i64 0
|
||||||
|
ret i64 %res
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user