[PATCH] D54583: PowerPC: Optimize SPE double parameter calling setup
Kei Thomsen via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 27 05:39:02 PDT 2019
kthomsen added a comment.
I found an issue with the SPE compare operations. The result of a efdcmpeq , efdcmpgt and efdcmplt is every time the GT-Bit in the Condition Register. This is adressed in one place of the PPCISelDAGToDAG.cpp, but not addressed for a second case of the code generation.
The diff of PPCISelDAGToDAG.cpp is:
--- PPCISelDAGToDAG.cpp 2019-03-12 15:35:45.000000000 +0100
+++ "\\ellcc\\PPCISelDAGToDAG.cpp" 2019-03-27 10:52:21.088326000 +0100
@@ -5039,6 +5038,32 @@ void PPCDAGToDAGISel::Select(SDNode *N)
PCC |= getBranchHint(PCC, FuncInfo, N->getOperand(4));
SDValue CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC, dl);
+
+ if (PPCSubTarget->hasSPE() && N->getOperand(2).getValueType().isFloatingPoint()) {
+ // For SPE instructions, the result is in GT bit of the CR
+ switch(CC) {
+ case ISD::SETOEQ:
+ case ISD::SETEQ:
+ case ISD::SETOLT:
+ case ISD::SETLT:
+ case ISD::SETOGT:
+ case ISD::SETGT:
+ PCC = PPC::PRED_GT;
+ break;
+ case ISD::SETUNE:
+ case ISD::SETNE:
+ case ISD::SETULE:
+ case ISD::SETLE:
+ case ISD::SETUGE:
+ case ISD::SETGE:
+ PCC = PPC::PRED_LE;
+ break;
+ default:
+ break;
+ }
+ }
+
+
SDValue Ops[] = { getI32Imm(PCC, dl), CondCode,
N->getOperand(4), N->getOperand(0) };
CurDAG->SelectNodeTo(N, PPC::BCC, MVT::Other, Ops);
The following testprogram is checking all methods. And the LIBC++ tests are now correctly compiled and running (about 1000 of 5800 failed before).
#include <stdio.h>
int teq(double a, double b)
{
printf("%lf == %lf\n",a,b);
if (a == b)
{
printf("equal\n");
return 1;
}
printf("!equal\n");
return 0;
}
int tne(double a, double b)
{
printf("%lf != %lf\n",a,b);
if (a != b)
{
printf("notequal\n");
return 1;
}
printf("!notequal\n");
return 0;
}
int tgt(double a, double b)
{
printf("%lf > %lf\n",a,b);
if (a > b)
{
printf("greater than\n");
return 1;
}
printf("!greater than\n");
return 0;
}
int tge(double a, double b)
{
printf("%lf >= %lf\n",a,b);
if (a >= b)
{
printf("greater equal\n");
return 1;
}
printf("!greater equal\n");
return 0;
}
int tlt(double a, double b)
{
printf("%lf < %lf\n",a,b);
if (a < b)
{
printf("less than\n");
return 1;
}
printf("!less than\n");
return 0;
}
int tle(double a, double b)
{
printf("%lf <= %lf\n",a,b);
if (a <= b)
{
printf("less equal\n");
return 1;
}
printf("!less equal\n");
return 0;
}
int main()
{
teq(5.5,5.5);
teq(5.5,5.6);
tne(5.5,5.6);
tne(5.5,5.5);
tgt(5.5,5.6);
tgt(5.5,5.5);
tgt(5.5,5.4);
tge(5.5,5.6);
tge(5.5,5.5);
tge(5.5,5.4);
tlt(5.5,5.6);
tlt(5.5,5.5);
tlt(5.5,5.4);
tle(5.5,5.6);
tle(5.5,5.5);
tle(5.5,5.4);
return 0;
}
The result is:
$ eq
5.500000 == 5.500000
equal
5.500000 == 5.600000
!equal
5.500000 != 5.600000
notequal
5.500000 != 5.500000
!notequal
5.500000 > 5.600000
!greater than
5.500000 > 5.500000
!greater than
5.500000 > 5.400000
greater than
5.500000 >= 5.600000
!greater equal
5.500000 >= 5.500000
greater equal
5.500000 >= 5.400000
greater equal
5.500000 < 5.600000
less than
5.500000 < 5.500000
!less than
5.500000 < 5.400000
!less than
5.500000 <= 5.600000
less equal
5.500000 <= 5.500000
less equal
5.500000 <= 5.400000
!less equal
I'm not sure if this fix is good for D54583 <https://reviews.llvm.org/D54583> or if you like to create a new one.
Best regards, Kei
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D54583/new/
https://reviews.llvm.org/D54583
More information about the llvm-commits
mailing list