mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
Not sure how CMPPS and CMPPD had already ever worked, I guess it didn't.
However with this fix it does now. Basically the operand order for the x86 target specific node is not the same as the instruction, but since the intrinsic need that specific order at the instruction definition, just change the order during legalization. Also, there were some wrong invertions of condition codes, such as GE => LE, GT => LT, fix that too. Fix PR10907. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139528 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
93474f5f7f
commit
8e03a821f9
@ -8445,16 +8445,25 @@ SDValue X86TargetLowering::LowerVSETCC(SDValue Op, SelectionDAG &DAG) const {
|
||||
unsigned Opc = EltVT == MVT::f32 ? X86ISD::CMPPS : X86ISD::CMPPD;
|
||||
bool Swap = false;
|
||||
|
||||
// SSE Condition code mapping:
|
||||
// 0 - EQ
|
||||
// 1 - LT
|
||||
// 2 - LE
|
||||
// 3 - UNORD
|
||||
// 4 - NEQ
|
||||
// 5 - NLT
|
||||
// 6 - NLE
|
||||
// 7 - ORD
|
||||
switch (SetCCOpcode) {
|
||||
default: break;
|
||||
case ISD::SETOEQ:
|
||||
case ISD::SETEQ: SSECC = 0; break;
|
||||
case ISD::SETOGT:
|
||||
case ISD::SETGT: Swap = true; // Fallthrough
|
||||
case ISD::SETLT:
|
||||
case ISD::SETOLT: SSECC = 1; break;
|
||||
case ISD::SETOGE:
|
||||
case ISD::SETGE: Swap = true; // Fallthrough
|
||||
case ISD::SETLT:
|
||||
case ISD::SETOLT: SSECC = 1; break;
|
||||
case ISD::SETOGT:
|
||||
case ISD::SETGT: Swap = true; // Fallthrough
|
||||
case ISD::SETLE:
|
||||
case ISD::SETOLE: SSECC = 2; break;
|
||||
case ISD::SETUO: SSECC = 3; break;
|
||||
@ -8473,20 +8482,20 @@ SDValue X86TargetLowering::LowerVSETCC(SDValue Op, SelectionDAG &DAG) const {
|
||||
if (SSECC == 8) {
|
||||
if (SetCCOpcode == ISD::SETUEQ) {
|
||||
SDValue UNORD, EQ;
|
||||
UNORD = DAG.getNode(Opc, dl, VT, Op0, Op1, DAG.getConstant(3, MVT::i8));
|
||||
EQ = DAG.getNode(Opc, dl, VT, Op0, Op1, DAG.getConstant(0, MVT::i8));
|
||||
UNORD = DAG.getNode(Opc, dl, VT, Op1, Op0, DAG.getConstant(3, MVT::i8));
|
||||
EQ = DAG.getNode(Opc, dl, VT, Op1, Op0, DAG.getConstant(0, MVT::i8));
|
||||
return DAG.getNode(ISD::OR, dl, VT, UNORD, EQ);
|
||||
}
|
||||
else if (SetCCOpcode == ISD::SETONE) {
|
||||
SDValue ORD, NEQ;
|
||||
ORD = DAG.getNode(Opc, dl, VT, Op0, Op1, DAG.getConstant(7, MVT::i8));
|
||||
NEQ = DAG.getNode(Opc, dl, VT, Op0, Op1, DAG.getConstant(4, MVT::i8));
|
||||
ORD = DAG.getNode(Opc, dl, VT, Op1, Op0, DAG.getConstant(7, MVT::i8));
|
||||
NEQ = DAG.getNode(Opc, dl, VT, Op1, Op0, DAG.getConstant(4, MVT::i8));
|
||||
return DAG.getNode(ISD::AND, dl, VT, ORD, NEQ);
|
||||
}
|
||||
llvm_unreachable("Illegal FP comparison");
|
||||
}
|
||||
// Handle all other FP comparisons here.
|
||||
return DAG.getNode(Opc, dl, VT, Op0, Op1, DAG.getConstant(SSECC, MVT::i8));
|
||||
return DAG.getNode(Opc, dl, VT, Op1, Op0, DAG.getConstant(SSECC, MVT::i8));
|
||||
}
|
||||
|
||||
// Break 256-bit integer vector compare into smaller ones.
|
||||
|
@ -82,4 +82,23 @@ define <8 x i64> @vsel_i648(<8 x i64> %v1, <8 x i64> %v2) {
|
||||
ret <8 x i64> %vsel
|
||||
}
|
||||
|
||||
;; TEST blend + compares
|
||||
; CHECK: A
|
||||
define <2 x double> @A(<2 x double> %x, <2 x double> %y) {
|
||||
; CHECK: vcmpltpd
|
||||
; CHECK: vblendvpd
|
||||
%max_is_x = fcmp oge <2 x double> %x, %y
|
||||
%max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
|
||||
ret <2 x double> %max
|
||||
}
|
||||
|
||||
; CHECK: B
|
||||
define <2 x double> @B(<2 x double> %x, <2 x double> %y) {
|
||||
; CHECK: vcmplepd
|
||||
; CHECK: vblendvpd
|
||||
%max_is_x = fcmp ogt <2 x double> %x, %y
|
||||
%max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
|
||||
ret <2 x double> %max
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,4 +44,22 @@ define <16 x i8> @vsel_i8(<16 x i8> %v1, <16 x i8> %v2) {
|
||||
ret <16 x i8> %vsel
|
||||
}
|
||||
|
||||
;; TEST blend + compares
|
||||
; CHECK: A
|
||||
define <2 x double> @A(<2 x double> %x, <2 x double> %y) {
|
||||
; CHECK: cmpltpd
|
||||
; CHECK: blendvpd
|
||||
%max_is_x = fcmp oge <2 x double> %x, %y
|
||||
%max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
|
||||
ret <2 x double> %max
|
||||
}
|
||||
|
||||
; CHECK: B
|
||||
define <2 x double> @B(<2 x double> %x, <2 x double> %y) {
|
||||
; CHECK: cmplepd
|
||||
; CHECK: blendvpd
|
||||
%max_is_x = fcmp ogt <2 x double> %x, %y
|
||||
%max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
|
||||
ret <2 x double> %max
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user