Skip to content

Commit 15a1780

Browse files
ajwockkpneal
authored andcommitted
[PowerPC] Replace subtract-from-zero float in version with fneg in PowerPC special fma compiler builtins
This is a re-revert with a corrected test. This patch adds a test for the PowerPC fma compiler builtins, some variations of which negate inputs and outputs. The code to generate IR for these builtins was untested before this patch. Originally, the code used the outdated method of subtracting floating point values from -0.0 as floating point negation. This patch remedies that. Patch by: Drew Wock <[email protected]> Differential Revision: https://reviews.llvm.org/D76949
1 parent a3220df commit 15a1780

File tree

3 files changed

+63
-24
lines changed

3 files changed

+63
-24
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14056,25 +14056,21 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
1405614056
Value *X = EmitScalarExpr(E->getArg(0));
1405714057
Value *Y = EmitScalarExpr(E->getArg(1));
1405814058
Value *Z = EmitScalarExpr(E->getArg(2));
14059-
Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
1406014059
llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
1406114060
switch (BuiltinID) {
1406214061
case PPC::BI__builtin_vsx_xvmaddadp:
1406314062
case PPC::BI__builtin_vsx_xvmaddasp:
1406414063
return Builder.CreateCall(F, {X, Y, Z});
1406514064
case PPC::BI__builtin_vsx_xvnmaddadp:
1406614065
case PPC::BI__builtin_vsx_xvnmaddasp:
14067-
return Builder.CreateFSub(Zero,
14068-
Builder.CreateCall(F, {X, Y, Z}), "sub");
14066+
return Builder.CreateFNeg(Builder.CreateCall(F, {X, Y, Z}), "neg");
1406914067
case PPC::BI__builtin_vsx_xvmsubadp:
1407014068
case PPC::BI__builtin_vsx_xvmsubasp:
14071-
return Builder.CreateCall(F,
14072-
{X, Y, Builder.CreateFSub(Zero, Z, "sub")});
14069+
return Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")});
1407314070
case PPC::BI__builtin_vsx_xvnmsubadp:
1407414071
case PPC::BI__builtin_vsx_xvnmsubasp:
14075-
Value *FsubRes =
14076-
Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
14077-
return Builder.CreateFSub(Zero, FsubRes, "sub");
14072+
return Builder.CreateFNeg(
14073+
Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}), "neg");
1407814074
}
1407914075
llvm_unreachable("Unknown FMA operation");
1408014076
return nullptr; // Suppress no-return warning

clang/test/CodeGen/builtins-ppc-fma.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %clang_cc1 -triple powerpc64le-gnu-linux \
2+
// RUN: -target-feature +altivec -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck \
3+
// RUN: %s
4+
5+
typedef __attribute__((vector_size(4 * sizeof(float)))) float vec_float;
6+
typedef __attribute__((vector_size(2 * sizeof(double)))) double vec_double;
7+
8+
volatile vec_double vd;
9+
volatile vec_float vf;
10+
11+
void test_fma(void) {
12+
vf = __builtin_vsx_xvmaddasp(vf, vf, vf);
13+
// CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}})
14+
15+
vd = __builtin_vsx_xvmaddadp(vd, vd, vd);
16+
// CHECK: @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}})
17+
18+
vf = __builtin_vsx_xvnmaddasp(vf, vf, vf);
19+
// CHECK: [[RESULT:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}})
20+
// CHECK: fneg <4 x float> [[RESULT]]
21+
22+
vd = __builtin_vsx_xvnmaddadp(vd, vd, vd);
23+
// CHECK: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}})
24+
// CHECK: fneg <2 x double> [[RESULT]]
25+
26+
vf = __builtin_vsx_xvmsubasp(vf, vf, vf);
27+
// CHECK: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}}
28+
// CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]])
29+
30+
vd = __builtin_vsx_xvmsubadp(vd, vd, vd);
31+
// CHECK: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}}
32+
// CHECK: <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]])
33+
34+
vf = __builtin_vsx_xvnmsubasp(vf, vf, vf);
35+
// CHECK: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}}
36+
// CHECK: [[RESULT2:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]])
37+
// CHECK: fneg <4 x float> [[RESULT2]]
38+
39+
vd = __builtin_vsx_xvnmsubadp(vd, vd, vd);
40+
// CHECK: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}}
41+
// CHECK: [[RESULT2:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]])
42+
// CHECK: fneg <2 x double> [[RESULT2]]
43+
}

clang/test/CodeGen/builtins-ppc-vsx.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -713,15 +713,15 @@ void test1() {
713713

714714
/* vec_msub */
715715
res_vf = vec_msub(vf, vf, vf);
716-
// CHECK: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{[0-9]+}}
716+
// CHECK: fneg <4 x float> %{{[0-9]+}}
717717
// CHECK-NEXT: call <4 x float> @llvm.fma.v4f32(<4 x float> %{{[0-9]+}}, <4 x float> %{{[0-9]+}}, <4 x float>
718-
// CHECK-LE: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{[0-9]+}}
718+
// CHECK-LE: fneg <4 x float> %{{[0-9]+}}
719719
// CHECK-LE-NEXT: call <4 x float> @llvm.fma.v4f32(<4 x float> %{{[0-9]+}}, <4 x float> %{{[0-9]+}}, <4 x float>
720720

721721
res_vd = vec_msub(vd, vd, vd);
722-
// CHECK: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{[0-9]+}}
722+
// CHECK: fneg <2 x double> %{{[0-9]+}}
723723
// CHECK-NEXT: call <2 x double> @llvm.fma.v2f64(<2 x double> %{{[0-9]+}}, <2 x double> %{{[0-9]+}}, <2 x double>
724-
// CHECK-LE: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{[0-9]+}}
724+
// CHECK-LE: fneg <2 x double> %{{[0-9]+}}
725725
// CHECK-LE-NEXT: call <2 x double> @llvm.fma.v2f64(<2 x double> %{{[0-9]+}}, <2 x double> %{{[0-9]+}}, <2 x double>
726726

727727
res_vsll = vec_mul(vsll, vsll);
@@ -750,31 +750,31 @@ void test1() {
750750

751751
res_vf = vec_nmadd(vf, vf, vf);
752752
// CHECK: [[FM:[0-9]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{[0-9]+}}, <4 x float> %{{[0-9]+}}, <4 x float> %{{[0-9]+}})
753-
// CHECK-NEXT: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %[[FM]]
753+
// CHECK-NEXT: fneg <4 x float> %[[FM]]
754754
// CHECK-LE: [[FM:[0-9]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{[0-9]+}}, <4 x float> %{{[0-9]+}}, <4 x float> %{{[0-9]+}})
755-
// CHECK-LE-NEXT: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %[[FM]]
755+
// CHECK-LE-NEXT: fneg <4 x float> %[[FM]]
756756

757757
res_vd = vec_nmadd(vd, vd, vd);
758758
// CHECK: [[FM:[0-9]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{[0-9]+}}, <2 x double> %{{[0-9]+}}, <2 x double> %{{[0-9]+}})
759-
// CHECK-NEXT: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %[[FM]]
759+
// CHECK-NEXT: fneg <2 x double> %[[FM]]
760760
// CHECK-LE: [[FM:[0-9]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{[0-9]+}}, <2 x double> %{{[0-9]+}}, <2 x double> %{{[0-9]+}})
761-
// CHECK-LE-NEXT: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %[[FM]]
761+
// CHECK-LE-NEXT: fneg <2 x double> %[[FM]]
762762

763763
res_vf = vec_nmsub(vf, vf, vf);
764-
// CHECK: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{[0-9]+}}
764+
// CHECK: fneg <4 x float> %{{[0-9]+}}
765765
// CHECK-NEXT: call <4 x float> @llvm.fma.v4f32(<4 x float> %{{[0-9]+}}, <4 x float> %{{[0-9]+}}, <4 x float>
766-
// CHECK: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{[0-9]+}}
767-
// CHECK-LE: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{[0-9]+}}
766+
// CHECK: fneg <4 x float> %{{[0-9]+}}
767+
// CHECK-LE: fneg <4 x float> %{{[0-9]+}}
768768
// CHECK-LE-NEXT: call <4 x float> @llvm.fma.v4f32(<4 x float> %{{[0-9]+}}, <4 x float> %{{[0-9]+}}, <4 x float>
769-
// CHECK-LE: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{[0-9]+}}
769+
// CHECK-LE: fneg <4 x float> %{{[0-9]+}}
770770

771771
res_vd = vec_nmsub(vd, vd, vd);
772-
// CHECK: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{[0-9]+}}
772+
// CHECK: fneg <2 x double> %{{[0-9]+}}
773773
// CHECK-NEXT: [[FM:[0-9]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{[0-9]+}}, <2 x double> %{{[0-9]+}}, <2 x double>
774-
// CHECK-NEXT: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %[[FM]]
775-
// CHECK-LE: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{[0-9]+}}
774+
// CHECK-NEXT: fneg <2 x double> %[[FM]]
775+
// CHECK-LE: fneg <2 x double> %{{[0-9]+}}
776776
// CHECK-LE-NEXT: [[FM:[0-9]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{[0-9]+}}, <2 x double> %{{[0-9]+}}, <2 x double>
777-
// CHECK-LE-NEXT: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %[[FM]]
777+
// CHECK-LE-NEXT: fneg <2 x double> %[[FM]]
778778

779779
/* vec_nor */
780780
res_vsll = vec_nor(vsll, vsll);

0 commit comments

Comments
 (0)