https://github.com/yairbenavraham updated https://github.com/llvm/llvm-project/pull/232660
>From c52dfeebf9d7831ca2d48975a4253c2a3593ba63 Mon Sep 17 00:00:00 2001 From: Yair Ben Avraham <[email protected]> Date: Fri, 16 Oct 2026 12:54:21 +0300 Subject: [PATCH] [CIR][AArch64] Migrate strict vector FMA tests Move test_vfma_f32, test_vfmaq_f32, and test_vfmaq_f64 from neon-intrinsics-constrained.c to neon/fused-multiply-constrained.c. The existing RUN lines cover classic CodeGen, CIR, and CIR-to-LLVM under strict floating-point exception handling. Preserve operand tracking and constrained FMA result checks, and match the destination file's FileCheck style. Remove the superseded legacy blocks; unconstrained coverage already lives in neon/fused-multiply.c. Follow-up to #218307. Assisted-by: Codex --- .../AArch64/neon-intrinsics-constrained.c | 102 ------------------ .../AArch64/neon/fused-multiply-constrained.c | 60 +++++++++++ 2 files changed, 60 insertions(+), 102 deletions(-) diff --git a/clang/test/CodeGen/AArch64/neon-intrinsics-constrained.c b/clang/test/CodeGen/AArch64/neon-intrinsics-constrained.c index 09f2aec4176b42..0e34273ff24d6b 100644 --- a/clang/test/CodeGen/AArch64/neon-intrinsics-constrained.c +++ b/clang/test/CodeGen/AArch64/neon-intrinsics-constrained.c @@ -251,108 +251,6 @@ float64x2_t test_vmlsq_f64(float64x2_t v1, float64x2_t v2, float64x2_t v3) { return vmlsq_f64(v1, v2, v3); } -// UNCONSTRAINED-LABEL: define dso_local <2 x float> @test_vfma_f32( -// UNCONSTRAINED-SAME: <2 x float> noundef [[V1:%.*]], <2 x float> noundef [[V2:%.*]], <2 x float> noundef [[V3:%.*]]) #[[ATTR0]] { -// UNCONSTRAINED-NEXT: [[ENTRY:.*:]] -// UNCONSTRAINED-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[V1]] to <2 x i32> -// UNCONSTRAINED-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[V2]] to <2 x i32> -// UNCONSTRAINED-NEXT: [[TMP2:%.*]] = bitcast <2 x float> [[V3]] to <2 x i32> -// UNCONSTRAINED-NEXT: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8> -// UNCONSTRAINED-NEXT: [[TMP4:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8> -// UNCONSTRAINED-NEXT: [[TMP5:%.*]] = bitcast <2 x i32> [[TMP2]] to <8 x i8> -// UNCONSTRAINED-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float> -// UNCONSTRAINED-NEXT: [[TMP7:%.*]] = bitcast <8 x i8> [[TMP4]] to <2 x float> -// UNCONSTRAINED-NEXT: [[TMP8:%.*]] = bitcast <8 x i8> [[TMP5]] to <2 x float> -// UNCONSTRAINED-NEXT: [[TMP9:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[TMP7]], <2 x float> [[TMP8]], <2 x float> [[TMP6]]) -// UNCONSTRAINED-NEXT: ret <2 x float> [[TMP9]] -// -// CONSTRAINED-LABEL: define dso_local <2 x float> @test_vfma_f32( -// CONSTRAINED-SAME: <2 x float> noundef [[V1:%.*]], <2 x float> noundef [[V2:%.*]], <2 x float> noundef [[V3:%.*]]) #[[ATTR0]] { -// CONSTRAINED-NEXT: [[ENTRY:.*:]] -// CONSTRAINED-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[V1]] to <2 x i32> -// CONSTRAINED-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[V2]] to <2 x i32> -// CONSTRAINED-NEXT: [[TMP2:%.*]] = bitcast <2 x float> [[V3]] to <2 x i32> -// CONSTRAINED-NEXT: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8> -// CONSTRAINED-NEXT: [[TMP4:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8> -// CONSTRAINED-NEXT: [[TMP5:%.*]] = bitcast <2 x i32> [[TMP2]] to <8 x i8> -// CONSTRAINED-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float> -// CONSTRAINED-NEXT: [[TMP7:%.*]] = bitcast <8 x i8> [[TMP4]] to <2 x float> -// CONSTRAINED-NEXT: [[TMP8:%.*]] = bitcast <8 x i8> [[TMP5]] to <2 x float> -// CONSTRAINED-NEXT: [[TMP9:%.*]] = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> [[TMP7]], <2 x float> [[TMP8]], <2 x float> [[TMP6]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR3]] -// CONSTRAINED-NEXT: ret <2 x float> [[TMP9]] -// -float32x2_t test_vfma_f32(float32x2_t v1, float32x2_t v2, float32x2_t v3) { - return vfma_f32(v1, v2, v3); -} - -// UNCONSTRAINED-LABEL: define dso_local <4 x float> @test_vfmaq_f32( -// UNCONSTRAINED-SAME: <4 x float> noundef [[V1:%.*]], <4 x float> noundef [[V2:%.*]], <4 x float> noundef [[V3:%.*]]) #[[ATTR0]] { -// UNCONSTRAINED-NEXT: [[ENTRY:.*:]] -// UNCONSTRAINED-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V1]] to <4 x i32> -// UNCONSTRAINED-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[V2]] to <4 x i32> -// UNCONSTRAINED-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[V3]] to <4 x i32> -// UNCONSTRAINED-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8> -// UNCONSTRAINED-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8> -// UNCONSTRAINED-NEXT: [[TMP5:%.*]] = bitcast <4 x i32> [[TMP2]] to <16 x i8> -// UNCONSTRAINED-NEXT: [[TMP6:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float> -// UNCONSTRAINED-NEXT: [[TMP7:%.*]] = bitcast <16 x i8> [[TMP4]] to <4 x float> -// UNCONSTRAINED-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <4 x float> -// UNCONSTRAINED-NEXT: [[TMP9:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> [[TMP7]], <4 x float> [[TMP8]], <4 x float> [[TMP6]]) -// UNCONSTRAINED-NEXT: ret <4 x float> [[TMP9]] -// -// CONSTRAINED-LABEL: define dso_local <4 x float> @test_vfmaq_f32( -// CONSTRAINED-SAME: <4 x float> noundef [[V1:%.*]], <4 x float> noundef [[V2:%.*]], <4 x float> noundef [[V3:%.*]]) #[[ATTR0]] { -// CONSTRAINED-NEXT: [[ENTRY:.*:]] -// CONSTRAINED-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V1]] to <4 x i32> -// CONSTRAINED-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[V2]] to <4 x i32> -// CONSTRAINED-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[V3]] to <4 x i32> -// CONSTRAINED-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8> -// CONSTRAINED-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8> -// CONSTRAINED-NEXT: [[TMP5:%.*]] = bitcast <4 x i32> [[TMP2]] to <16 x i8> -// CONSTRAINED-NEXT: [[TMP6:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float> -// CONSTRAINED-NEXT: [[TMP7:%.*]] = bitcast <16 x i8> [[TMP4]] to <4 x float> -// CONSTRAINED-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <4 x float> -// CONSTRAINED-NEXT: [[TMP9:%.*]] = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> [[TMP7]], <4 x float> [[TMP8]], <4 x float> [[TMP6]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR3]] -// CONSTRAINED-NEXT: ret <4 x float> [[TMP9]] -// -float32x4_t test_vfmaq_f32(float32x4_t v1, float32x4_t v2, float32x4_t v3) { - return vfmaq_f32(v1, v2, v3); -} - -// UNCONSTRAINED-LABEL: define dso_local <2 x double> @test_vfmaq_f64( -// UNCONSTRAINED-SAME: <2 x double> noundef [[V1:%.*]], <2 x double> noundef [[V2:%.*]], <2 x double> noundef [[V3:%.*]]) #[[ATTR0]] { -// UNCONSTRAINED-NEXT: [[ENTRY:.*:]] -// UNCONSTRAINED-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[V1]] to <2 x i64> -// UNCONSTRAINED-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[V2]] to <2 x i64> -// UNCONSTRAINED-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[V3]] to <2 x i64> -// UNCONSTRAINED-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8> -// UNCONSTRAINED-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8> -// UNCONSTRAINED-NEXT: [[TMP5:%.*]] = bitcast <2 x i64> [[TMP2]] to <16 x i8> -// UNCONSTRAINED-NEXT: [[TMP6:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double> -// UNCONSTRAINED-NEXT: [[TMP7:%.*]] = bitcast <16 x i8> [[TMP4]] to <2 x double> -// UNCONSTRAINED-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <2 x double> -// UNCONSTRAINED-NEXT: [[TMP9:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> [[TMP7]], <2 x double> [[TMP8]], <2 x double> [[TMP6]]) -// UNCONSTRAINED-NEXT: ret <2 x double> [[TMP9]] -// -// CONSTRAINED-LABEL: define dso_local <2 x double> @test_vfmaq_f64( -// CONSTRAINED-SAME: <2 x double> noundef [[V1:%.*]], <2 x double> noundef [[V2:%.*]], <2 x double> noundef [[V3:%.*]]) #[[ATTR0]] { -// CONSTRAINED-NEXT: [[ENTRY:.*:]] -// CONSTRAINED-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[V1]] to <2 x i64> -// CONSTRAINED-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[V2]] to <2 x i64> -// CONSTRAINED-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[V3]] to <2 x i64> -// CONSTRAINED-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8> -// CONSTRAINED-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8> -// CONSTRAINED-NEXT: [[TMP5:%.*]] = bitcast <2 x i64> [[TMP2]] to <16 x i8> -// CONSTRAINED-NEXT: [[TMP6:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double> -// CONSTRAINED-NEXT: [[TMP7:%.*]] = bitcast <16 x i8> [[TMP4]] to <2 x double> -// CONSTRAINED-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <2 x double> -// CONSTRAINED-NEXT: [[TMP9:%.*]] = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> [[TMP7]], <2 x double> [[TMP8]], <2 x double> [[TMP6]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR3]] -// CONSTRAINED-NEXT: ret <2 x double> [[TMP9]] -// -float64x2_t test_vfmaq_f64(float64x2_t v1, float64x2_t v2, float64x2_t v3) { - return vfmaq_f64(v1, v2, v3); -} - // UNCONSTRAINED-LABEL: define dso_local <2 x float> @test_vfms_f32( // UNCONSTRAINED-SAME: <2 x float> noundef [[V1:%.*]], <2 x float> noundef [[V2:%.*]], <2 x float> noundef [[V3:%.*]]) #[[ATTR0]] { // UNCONSTRAINED-NEXT: [[ENTRY:.*:]] diff --git a/clang/test/CodeGen/AArch64/neon/fused-multiply-constrained.c b/clang/test/CodeGen/AArch64/neon/fused-multiply-constrained.c index 52ee3f20628511..a782c835a2fdab 100644 --- a/clang/test/CodeGen/AArch64/neon/fused-multiply-constrained.c +++ b/clang/test/CodeGen/AArch64/neon/fused-multiply-constrained.c @@ -6,6 +6,26 @@ #include <arm_neon.h> +// LLVM-LABEL: @test_vfma_f32( +// CIR-LABEL: @vfma_f32( +float32x2_t test_vfma_f32(float32x2_t a, float32x2_t b, float32x2_t c) { +// CIR: cir.fma %{{.*}}, %{{.*}}, %{{.*}} : !cir.vector<2 x !cir.float> fenv<dynamic_rounding_mode = tonearest, except_mode = unknown, strict_except = true> + +// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]], <2 x float> {{.*}} [[B:%.*]], <2 x float> {{.*}} [[C:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <2 x float> [[A]] to <2 x i32> +// LLVM: [[B_I:%.*]] = bitcast <2 x float> [[B]] to <2 x i32> +// LLVM: [[C_I:%.*]] = bitcast <2 x float> [[C]] to <2 x i32> +// LLVM: [[A_BYTES:%.*]] = bitcast <2 x i32> [[A_I]] to <8 x i8> +// LLVM: [[B_BYTES:%.*]] = bitcast <2 x i32> [[B_I]] to <8 x i8> +// LLVM: [[C_BYTES:%.*]] = bitcast <2 x i32> [[C_I]] to <8 x i8> +// LLVM: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_BYTES]] to <2 x float> +// LLVM: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_BYTES]] to <2 x float> +// LLVM: [[C_CAST:%.*]] = bitcast <8 x i8> [[C_BYTES]] to <2 x float> +// LLVM: [[FMA:%.*]] = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> [[B_CAST]], <2 x float> [[C_CAST]], <2 x float> [[A_CAST]], metadata !"round.tonearest", metadata !"fpexcept.strict") +// LLVM: ret <2 x float> [[FMA]] + return vfma_f32(a, b, c); +} + // LLVM-LABEL: @test_vfma_f64( // CIR-LABEL: @vfma_f64( float64x1_t test_vfma_f64(float64x1_t a, float64x1_t b, float64x1_t c) { @@ -29,6 +49,46 @@ float64x1_t test_vfma_f64(float64x1_t a, float64x1_t b, float64x1_t c) { return vfma_f64(a, b, c); } +// LLVM-LABEL: @test_vfmaq_f32( +// CIR-LABEL: @vfmaq_f32( +float32x4_t test_vfmaq_f32(float32x4_t a, float32x4_t b, float32x4_t c) { +// CIR: cir.fma %{{.*}}, %{{.*}}, %{{.*}} : !cir.vector<4 x !cir.float> fenv<dynamic_rounding_mode = tonearest, except_mode = unknown, strict_except = true> + +// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]], <4 x float> {{.*}} [[B:%.*]], <4 x float> {{.*}} [[C:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <4 x float> [[A]] to <4 x i32> +// LLVM: [[B_I:%.*]] = bitcast <4 x float> [[B]] to <4 x i32> +// LLVM: [[C_I:%.*]] = bitcast <4 x float> [[C]] to <4 x i32> +// LLVM: [[A_BYTES:%.*]] = bitcast <4 x i32> [[A_I]] to <16 x i8> +// LLVM: [[B_BYTES:%.*]] = bitcast <4 x i32> [[B_I]] to <16 x i8> +// LLVM: [[C_BYTES:%.*]] = bitcast <4 x i32> [[C_I]] to <16 x i8> +// LLVM: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_BYTES]] to <4 x float> +// LLVM: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_BYTES]] to <4 x float> +// LLVM: [[C_CAST:%.*]] = bitcast <16 x i8> [[C_BYTES]] to <4 x float> +// LLVM: [[FMA:%.*]] = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> [[B_CAST]], <4 x float> [[C_CAST]], <4 x float> [[A_CAST]], metadata !"round.tonearest", metadata !"fpexcept.strict") +// LLVM: ret <4 x float> [[FMA]] + return vfmaq_f32(a, b, c); +} + +// LLVM-LABEL: @test_vfmaq_f64( +// CIR-LABEL: @vfmaq_f64( +float64x2_t test_vfmaq_f64(float64x2_t a, float64x2_t b, float64x2_t c) { +// CIR: cir.fma %{{.*}}, %{{.*}}, %{{.*}} : !cir.vector<2 x !cir.double> fenv<dynamic_rounding_mode = tonearest, except_mode = unknown, strict_except = true> + +// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]], <2 x double> {{.*}} [[B:%.*]], <2 x double> {{.*}} [[C:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <2 x double> [[A]] to <2 x i64> +// LLVM: [[B_I:%.*]] = bitcast <2 x double> [[B]] to <2 x i64> +// LLVM: [[C_I:%.*]] = bitcast <2 x double> [[C]] to <2 x i64> +// LLVM: [[A_BYTES:%.*]] = bitcast <2 x i64> [[A_I]] to <16 x i8> +// LLVM: [[B_BYTES:%.*]] = bitcast <2 x i64> [[B_I]] to <16 x i8> +// LLVM: [[C_BYTES:%.*]] = bitcast <2 x i64> [[C_I]] to <16 x i8> +// LLVM: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_BYTES]] to <2 x double> +// LLVM: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_BYTES]] to <2 x double> +// LLVM: [[C_CAST:%.*]] = bitcast <16 x i8> [[C_BYTES]] to <2 x double> +// LLVM: [[FMA:%.*]] = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> [[B_CAST]], <2 x double> [[C_CAST]], <2 x double> [[A_CAST]], metadata !"round.tonearest", metadata !"fpexcept.strict") +// LLVM: ret <2 x double> [[FMA]] + return vfmaq_f64(a, b, c); +} + // ALL-LABEL: @test_vfma_laneq_f64( float64x1_t test_vfma_laneq_f64(float64x1_t a, float64x1_t b, float64x2_t v) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
