Skip to content

Commit ba87430

Browse files
ajwockkpneal
authored andcommitted
[PowerPC] Replace subtract-from-zero float in version with fneg in PowerPC special fma compiler builtins
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 9657446 commit ba87430

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13214,25 +13214,24 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
1321413214
Value *X = EmitScalarExpr(E->getArg(0));
1321513215
Value *Y = EmitScalarExpr(E->getArg(1));
1321613216
Value *Z = EmitScalarExpr(E->getArg(2));
13217-
Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
1321813217
llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
1321913218
switch (BuiltinID) {
1322013219
case PPC::BI__builtin_vsx_xvmaddadp:
1322113220
case PPC::BI__builtin_vsx_xvmaddasp:
1322213221
return Builder.CreateCall(F, {X, Y, Z});
13222+
1322313223
case PPC::BI__builtin_vsx_xvnmaddadp:
1322413224
case PPC::BI__builtin_vsx_xvnmaddasp:
13225-
return Builder.CreateFSub(Zero,
13226-
Builder.CreateCall(F, {X, Y, Z}), "sub");
13225+
return Builder.CreateFNeg(Builder.CreateCall(F, {X, Y, Z}), "neg");
13226+
1322713227
case PPC::BI__builtin_vsx_xvmsubadp:
1322813228
case PPC::BI__builtin_vsx_xvmsubasp:
13229-
return Builder.CreateCall(F,
13230-
{X, Y, Builder.CreateFSub(Zero, Z, "sub")});
13229+
return Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")});
13230+
1323113231
case PPC::BI__builtin_vsx_xvnmsubadp:
1323213232
case PPC::BI__builtin_vsx_xvnmsubasp:
13233-
Value *FsubRes =
13234-
Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
13235-
return Builder.CreateFSub(Zero, FsubRes, "sub");
13233+
return Builder.CreateFNeg(
13234+
Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}), "neg");
1323613235
}
1323713236
llvm_unreachable("Unknown FMA operation");
1323813237
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: fneg <2 x double> [[RESULT]]
32+
// CHECK: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}})
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.v2f64(<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+
}

0 commit comments

Comments
 (0)