kpn created this revision. kpn added reviewers: steven.zhang, nemanjai. kpn added a project: clang. Herald added subscribers: shchenz, kbarton. kpn requested review of this revision. Herald added a subscriber: cfe-commits.
Currently clang is not correctly retrieving from the AST the metadata for constrained FP builtins. This patch fixes that for the PowerPC specific builtins. For previous work in this vein see D92122 <https://reviews.llvm.org/D92122> for example. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D94186 Files: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/builtins-ppc-fma.c clang/test/CodeGen/builtins-ppc-fpconstrained.c
Index: clang/test/CodeGen/builtins-ppc-fpconstrained.c =================================================================== --- clang/test/CodeGen/builtins-ppc-fpconstrained.c +++ clang/test/CodeGen/builtins-ppc-fpconstrained.c @@ -2,16 +2,23 @@ // RUN: %clang_cc1 -triple powerpc64le-gnu-linux -target-feature +vsx \ // RUN: -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-UNCONSTRAINED %s // RUN: %clang_cc1 -triple powerpc64le-gnu-linux -target-feature +vsx \ -// RUN: -ffp-exception-behavior=strict -emit-llvm %s -o - | FileCheck \ -// RUN: --check-prefix=CHECK-CONSTRAINED -vv %s +// RUN: -ffp-exception-behavior=maytrap -DSTRICT=1 -emit-llvm %s -o - | \ +// RUN: FileCheck --check-prefix=CHECK-CONSTRAINED -vv %s // RUN: %clang_cc1 -triple powerpc64le-gnu-linux -target-feature +vsx \ // RUN: -fallow-half-arguments-and-returns -S -o - %s | \ // RUN: FileCheck --check-prefix=CHECK-ASM --check-prefix=NOT-FIXME-CHECK %s // RUN: %clang_cc1 -triple powerpc64le-gnu-linux -target-feature +vsx \ -// RUN: -fallow-half-arguments-and-returns -S -ffp-exception-behavior=strict \ -// RUN: -o - %s | FileCheck --check-prefix=CHECK-ASM \ +// RUN: -fallow-half-arguments-and-returns -S -ffp-exception-behavior=maytrap \ +// RUN: -DSTRICT=1 -o - %s | FileCheck --check-prefix=CHECK-ASM \ // RUN: --check-prefix=FIXME-CHECK %s +#ifdef STRICT +// Test that the constrained intrinsics are picking up the exception +// metadata from the AST instead of the global default from the command line. + +#pragma float_control(except, on) +#endif + typedef __attribute__((vector_size(4 * sizeof(float)))) float vec_float; typedef __attribute__((vector_size(2 * sizeof(double)))) double vec_double; Index: clang/test/CodeGen/builtins-ppc-fma.c =================================================================== --- clang/test/CodeGen/builtins-ppc-fma.c +++ clang/test/CodeGen/builtins-ppc-fma.c @@ -1,6 +1,17 @@ // RUN: %clang_cc1 -triple powerpc64le-gnu-linux \ -// RUN: -target-feature +altivec -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck \ +// RUN: -target-feature +altivec -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck --check-prefix=NOSTRICT --check-prefix=SHARED \ // RUN: %s +// RUN: %clang_cc1 -triple powerpc64le-gnu-linux \ +// RUN: -ffp-exception-behavior=maytrap -DSTRICT=1 \ +// RUN: -target-feature +altivec -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck --check-prefix=STRICT --check-prefix=SHARED \ +// RUN: %s + +#ifdef STRICT +// Test that the constrained intrinsics are picking up the exception +// metadata from the AST instead of the global default from the command line. + +#pragma float_control(except, on) +#endif typedef __attribute__((vector_size(4 * sizeof(float)))) float vec_float; typedef __attribute__((vector_size(2 * sizeof(double)))) double vec_double; @@ -10,34 +21,42 @@ void test_fma(void) { vf = __builtin_vsx_xvmaddasp(vf, vf, vf); - // CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + // NOSTRICT: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + // STRICT: @llvm.experimental.constrained.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") vd = __builtin_vsx_xvmaddadp(vd, vd, vd); - // CHECK: @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + // NOSTRICT: @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + // STRICT: @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") vf = __builtin_vsx_xvnmaddasp(vf, vf, vf); - // CHECK: [[RESULT:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) - // CHECK: fneg <4 x float> [[RESULT]] + // NOSTRICT: [[RESULT:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + // STRICT: [[RESULT:%[^ ]+]] = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + // SHARED: fneg <4 x float> [[RESULT]] vd = __builtin_vsx_xvnmaddadp(vd, vd, vd); - // CHECK: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) - // CHECK: fneg <2 x double> [[RESULT]] + // NOSTRICT: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + // STRICT: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + // SHARED: fneg <2 x double> [[RESULT]] vf = __builtin_vsx_xvmsubasp(vf, vf, vf); - // CHECK: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} - // CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) + // SHARED: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} + // NOSTRICT: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) + // STRICT: @llvm.experimental.constrained.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]], metadata !"round.tonearest", metadata !"fpexcept.strict") vd = __builtin_vsx_xvmsubadp(vd, vd, vd); - // CHECK: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}} - // CHECK: <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]]) + // SHARED: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}} + // NOSTRICT: <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]]) + // STRICT: <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]], metadata !"round.tonearest", metadata !"fpexcept.strict") vf = __builtin_vsx_xvnmsubasp(vf, vf, vf); - // CHECK: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} - // CHECK: [[RESULT2:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) - // CHECK: fneg <4 x float> [[RESULT2]] + // SHARED: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} + // NOSTRICT: [[RESULT2:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) + // STRICT: [[RESULT2:%[^ ]+]] = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]], metadata !"round.tonearest", metadata !"fpexcept.strict") + // SHARED: fneg <4 x float> [[RESULT2]] vd = __builtin_vsx_xvnmsubadp(vd, vd, vd); - // CHECK: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}} - // CHECK: [[RESULT2:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]]) - // CHECK: fneg <2 x double> [[RESULT2]] + // SHARED: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}} + // NOSTRICT: [[RESULT2:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]]) + // STRICT: [[RESULT2:%[^ ]+]] = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]], metadata !"round.tonearest", metadata !"fpexcept.strict") + // SHARED: fneg <2 x double> [[RESULT2]] } Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -14526,6 +14526,7 @@ llvm::Type *ResultType = ConvertType(E->getType()); Value *X = EmitScalarExpr(E->getArg(0)); if (Builder.getIsFPConstrained()) { + CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E); llvm::Function *F = CGM.getIntrinsic( Intrinsic::experimental_constrained_sqrt, ResultType); return Builder.CreateConstrainedFPCall(F, X); @@ -14670,8 +14671,13 @@ ? Intrinsic::experimental_constrained_trunc : Intrinsic::trunc; llvm::Function *F = CGM.getIntrinsic(ID, ResultType); - return Builder.getIsFPConstrained() ? Builder.CreateConstrainedFPCall(F, X) - : Builder.CreateCall(F, X); + if (Builder.getIsFPConstrained()) { + CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E); + return Builder.CreateConstrainedFPCall(F, X); + } + else { + return Builder.CreateCall(F, X); + } } // Absolute value @@ -14704,35 +14710,47 @@ switch (BuiltinID) { case PPC::BI__builtin_vsx_xvmaddadp: case PPC::BI__builtin_vsx_xvmaddasp: - if (Builder.getIsFPConstrained()) + if (Builder.getIsFPConstrained()) { + CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E); return Builder.CreateConstrainedFPCall(F, {X, Y, Z}); - else + } + else { return Builder.CreateCall(F, {X, Y, Z}); + } case PPC::BI__builtin_vsx_xvnmaddadp: case PPC::BI__builtin_vsx_xvnmaddasp: - if (Builder.getIsFPConstrained()) + if (Builder.getIsFPConstrained()) { + CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E); return Builder.CreateFNeg( Builder.CreateConstrainedFPCall(F, {X, Y, Z}), "neg"); - else + } + else { return Builder.CreateFNeg(Builder.CreateCall(F, {X, Y, Z}), "neg"); + } case PPC::BI__builtin_vsx_xvmsubadp: case PPC::BI__builtin_vsx_xvmsubasp: - if (Builder.getIsFPConstrained()) + if (Builder.getIsFPConstrained()) { + CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E); return Builder.CreateConstrainedFPCall( F, {X, Y, Builder.CreateFNeg(Z, "neg")}); - else + } + else { return Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}); + } case PPC::BI__builtin_vsx_xvnmsubadp: case PPC::BI__builtin_vsx_xvnmsubasp: - if (Builder.getIsFPConstrained()) + if (Builder.getIsFPConstrained()) { + CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E); return Builder.CreateFNeg( Builder.CreateConstrainedFPCall( F, {X, Y, Builder.CreateFNeg(Z, "neg")}), "neg"); - else + } + else { return Builder.CreateFNeg( Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}), "neg"); + } } llvm_unreachable("Unknown FMA operation"); return nullptr; // Suppress no-return warning
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits