https://github.com/yairbenavraham updated https://github.com/llvm/llvm-project/pull/207022
>From fdda7a24b3b7e83720b8d99c24e2bbf54a3ef2f0 Mon Sep 17 00:00:00 2001 From: Yair Ben Avraham <[email protected]> Date: Wed, 1 Jul 2026 09:43:51 +0300 Subject: [PATCH 1/2] [CIR][AArch64] Move vfms vector tests Move the vfms_f32, vfms_f64, vfmsq_f32, and vfmsq_f64 coverage from neon-intrinsics.c into neon/fused-multiply.c. The new location adds direct LLVM, CIR-to-LLVM, and CIR RUN-line coverage while preserving strong operand-flow checks and removing the superseded legacy tests. --- clang/test/CodeGen/AArch64/neon-intrinsics.c | 83 ---------------- .../CodeGen/AArch64/neon/fused-multiply.c | 96 +++++++++++++++++++ 2 files changed, 96 insertions(+), 83 deletions(-) diff --git a/clang/test/CodeGen/AArch64/neon-intrinsics.c b/clang/test/CodeGen/AArch64/neon-intrinsics.c index 8e03ea78e2fd1..3213d12d42c7b 100644 --- a/clang/test/CodeGen/AArch64/neon-intrinsics.c +++ b/clang/test/CodeGen/AArch64/neon-intrinsics.c @@ -487,66 +487,6 @@ float64x2_t test_vmlsq_f64(float64x2_t v1, float64x2_t v2, float64x2_t v3) { return vmlsq_f64(v1, v2, v3); } -// CHECK-LABEL: define dso_local <2 x float> @test_vfms_f32( -// CHECK-SAME: <2 x float> noundef [[V1:%.*]], <2 x float> noundef [[V2:%.*]], <2 x float> noundef [[V3:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[FNEG_I:%.*]] = fneg <2 x float> [[V2]] -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[V1]] to <2 x i32> -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[FNEG_I]] to <2 x i32> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x float> [[V3]] to <2 x i32> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <2 x i32> [[TMP2]] to <8 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <8 x i8> [[TMP4]] to <2 x float> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <8 x i8> [[TMP5]] to <2 x float> -// CHECK-NEXT: [[TMP9:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[TMP7]], <2 x float> [[TMP8]], <2 x float> [[TMP6]]) -// CHECK-NEXT: ret <2 x float> [[TMP9]] -// -float32x2_t test_vfms_f32(float32x2_t v1, float32x2_t v2, float32x2_t v3) { - return vfms_f32(v1, v2, v3); -} - -// CHECK-LABEL: define dso_local <4 x float> @test_vfmsq_f32( -// CHECK-SAME: <4 x float> noundef [[V1:%.*]], <4 x float> noundef [[V2:%.*]], <4 x float> noundef [[V3:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[FNEG_I:%.*]] = fneg <4 x float> [[V2]] -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V1]] to <4 x i32> -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[FNEG_I]] to <4 x i32> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[V3]] to <4 x i32> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <4 x i32> [[TMP2]] to <16 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <16 x i8> [[TMP4]] to <4 x float> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <4 x float> -// CHECK-NEXT: [[TMP9:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> [[TMP7]], <4 x float> [[TMP8]], <4 x float> [[TMP6]]) -// CHECK-NEXT: ret <4 x float> [[TMP9]] -// -float32x4_t test_vfmsq_f32(float32x4_t v1, float32x4_t v2, float32x4_t v3) { - return vfmsq_f32(v1, v2, v3); -} - -// CHECK-LABEL: define dso_local <2 x double> @test_vfmsq_f64( -// CHECK-SAME: <2 x double> noundef [[V1:%.*]], <2 x double> noundef [[V2:%.*]], <2 x double> noundef [[V3:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[FNEG_I:%.*]] = fneg <2 x double> [[V2]] -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[V1]] to <2 x i64> -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[FNEG_I]] to <2 x i64> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[V3]] to <2 x i64> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <2 x i64> [[TMP2]] to <16 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <16 x i8> [[TMP4]] to <2 x double> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <2 x double> -// CHECK-NEXT: [[TMP9:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> [[TMP7]], <2 x double> [[TMP8]], <2 x double> [[TMP6]]) -// CHECK-NEXT: ret <2 x double> [[TMP9]] -// -float64x2_t test_vfmsq_f64(float64x2_t v1, float64x2_t v2, float64x2_t v3) { - return vfmsq_f64(v1, v2, v3); -} - // CHECK-LABEL: define dso_local <2 x double> @test_vdivq_f64( // CHECK-SAME: <2 x double> noundef [[V1:%.*]], <2 x double> noundef [[V2:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] @@ -15914,29 +15854,6 @@ float64x1_t test_vmls_f64(float64x1_t a, float64x1_t b, float64x1_t c) { return vmls_f64(a, b, c); } -// CHECK-LABEL: define dso_local <1 x double> @test_vfms_f64( -// CHECK-SAME: <1 x double> noundef [[A:%.*]], <1 x double> noundef [[B:%.*]], <1 x double> noundef [[C:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[FNEG_I:%.*]] = fneg <1 x double> [[B]] -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x double> [[A]] to i64 -// CHECK-NEXT: [[__P0_ADDR_I_I_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP0]], i32 0 -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <1 x double> [[FNEG_I]] to i64 -// CHECK-NEXT: [[__P1_ADDR_I_I_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP1]], i32 0 -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <1 x double> [[C]] to i64 -// CHECK-NEXT: [[__P2_ADDR_I_I_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP2]], i32 0 -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <1 x i64> [[__P0_ADDR_I_I_SROA_0_0_VEC_INSERT]] to <8 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <1 x i64> [[__P1_ADDR_I_I_SROA_0_0_VEC_INSERT]] to <8 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <1 x i64> [[__P2_ADDR_I_I_SROA_0_0_VEC_INSERT]] to <8 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP3]] to <1 x double> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <8 x i8> [[TMP4]] to <1 x double> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <8 x i8> [[TMP5]] to <1 x double> -// CHECK-NEXT: [[TMP9:%.*]] = call <1 x double> @llvm.fma.v1f64(<1 x double> [[TMP7]], <1 x double> [[TMP8]], <1 x double> [[TMP6]]) -// CHECK-NEXT: ret <1 x double> [[TMP9]] -// -float64x1_t test_vfms_f64(float64x1_t a, float64x1_t b, float64x1_t c) { - return vfms_f64(a, b, c); -} - // CHECK-LABEL: define dso_local <1 x double> @test_vabd_f64( // CHECK-SAME: <1 x double> noundef [[A:%.*]], <1 x double> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] diff --git a/clang/test/CodeGen/AArch64/neon/fused-multiply.c b/clang/test/CodeGen/AArch64/neon/fused-multiply.c index 71bb3de9e826e..ba1219b424576 100644 --- a/clang/test/CodeGen/AArch64/neon/fused-multiply.c +++ b/clang/test/CodeGen/AArch64/neon/fused-multiply.c @@ -404,3 +404,99 @@ float64_t test_vfmad_laneq_f64(float64_t a, float64_t b, float64x2_t c) { // LLVM: ret double [[FMA]] return vfmad_laneq_f64(a, b, c, 1); } + +//===------------------------------------------------------===// +// 2.1.1.2.5 Fused multiply-subtract forms +//===------------------------------------------------------===// + +// LLVM-LABEL: @test_vfms_f32( +// CIR-LABEL: @vfms_f32( +float32x2_t test_vfms_f32(float32x2_t a, float32x2_t b, float32x2_t c) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<2 x !cir.float> +// CIR: cir.call @vfma_f32(%{{.*}}, [[NEG]], %{{.*}}) : + +// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]], <2 x float> {{.*}} [[B:%.*]], <2 x float> {{.*}} [[C:%.*]]) {{.*}} { +// LLVM: [[NEG:%.*]] = fneg <2 x float> [[B]] +// LLVM-NEXT: [[A_I:%.*]] = bitcast <2 x float> [[A]] to <2 x i32> +// LLVM-NEXT: [[B_I:%.*]] = bitcast <2 x float> [[NEG]] to <2 x i32> +// LLVM-NEXT: [[C_I:%.*]] = bitcast <2 x float> [[C]] to <2 x i32> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <2 x i32> [[A_I]] to <8 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <2 x i32> [[B_I]] to <8 x i8> +// LLVM-NEXT: [[C_BYTES:%.*]] = bitcast <2 x i32> [[C_I]] to <8 x i8> +// LLVM-NEXT: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_BYTES]] to <2 x float> +// LLVM-NEXT: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_BYTES]] to <2 x float> +// LLVM-NEXT: [[C_CAST:%.*]] = bitcast <8 x i8> [[C_BYTES]] to <2 x float> +// LLVM-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[B_CAST]], <2 x float> [[C_CAST]], <2 x float> [[A_CAST]]) +// LLVM-NEXT: ret <2 x float> [[FMA]] + return vfms_f32(a, b, c); +} + +// LLVM-LABEL: @test_vfms_f64( +// CIR-LABEL: @vfms_f64( +float64x1_t test_vfms_f64(float64x1_t a, float64x1_t b, float64x1_t c) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<1 x !cir.double> +// CIR: cir.call @vfma_f64(%{{.*}}, [[NEG]], %{{.*}}) : + +// LLVM-SAME: <1 x double> {{.*}} [[A:%.*]], <1 x double> {{.*}} [[B:%.*]], <1 x double> {{.*}} [[C:%.*]]) {{.*}} { +// LLVM: [[NEG:%.*]] = fneg <1 x double> [[B]] +// LLVM-NEXT: [[A_I:%.*]] = bitcast <1 x double> [[A]] to i64 +// LLVM-NEXT: [[A_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[A_I]], i32 0 +// LLVM-NEXT: [[B_I:%.*]] = bitcast <1 x double> [[NEG]] to i64 +// LLVM-NEXT: [[B_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[B_I]], i32 0 +// LLVM-NEXT: [[C_I:%.*]] = bitcast <1 x double> [[C]] to i64 +// LLVM-NEXT: [[C_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[C_I]], i32 0 +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <1 x i64> [[A_INSERT]] to <8 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <1 x i64> [[B_INSERT]] to <8 x i8> +// LLVM-NEXT: [[C_BYTES:%.*]] = bitcast <1 x i64> [[C_INSERT]] to <8 x i8> +// LLVM-NEXT: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_BYTES]] to <1 x double> +// LLVM-NEXT: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_BYTES]] to <1 x double> +// LLVM-NEXT: [[C_CAST:%.*]] = bitcast <8 x i8> [[C_BYTES]] to <1 x double> +// LLVM-NEXT: [[FMA:%.*]] = call <1 x double> @llvm.fma.v1f64(<1 x double> [[B_CAST]], <1 x double> [[C_CAST]], <1 x double> [[A_CAST]]) +// LLVM-NEXT: ret <1 x double> [[FMA]] + return vfms_f64(a, b, c); +} + +// LLVM-LABEL: @test_vfmsq_f32( +// CIR-LABEL: @vfmsq_f32( +float32x4_t test_vfmsq_f32(float32x4_t a, float32x4_t b, float32x4_t c) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<4 x !cir.float> +// CIR: cir.call @vfmaq_f32(%{{.*}}, [[NEG]], %{{.*}}) : + +// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]], <4 x float> {{.*}} [[B:%.*]], <4 x float> {{.*}} [[C:%.*]]) {{.*}} { +// LLVM: [[NEG:%.*]] = fneg <4 x float> [[B]] +// LLVM-NEXT: [[A_I:%.*]] = bitcast <4 x float> [[A]] to <4 x i32> +// LLVM-NEXT: [[B_I:%.*]] = bitcast <4 x float> [[NEG]] to <4 x i32> +// LLVM-NEXT: [[C_I:%.*]] = bitcast <4 x float> [[C]] to <4 x i32> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <4 x i32> [[A_I]] to <16 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <4 x i32> [[B_I]] to <16 x i8> +// LLVM-NEXT: [[C_BYTES:%.*]] = bitcast <4 x i32> [[C_I]] to <16 x i8> +// LLVM-NEXT: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_BYTES]] to <4 x float> +// LLVM-NEXT: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_BYTES]] to <4 x float> +// LLVM-NEXT: [[C_CAST:%.*]] = bitcast <16 x i8> [[C_BYTES]] to <4 x float> +// LLVM-NEXT: [[FMA:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> [[B_CAST]], <4 x float> [[C_CAST]], <4 x float> [[A_CAST]]) +// LLVM-NEXT: ret <4 x float> [[FMA]] + return vfmsq_f32(a, b, c); +} + +// LLVM-LABEL: @test_vfmsq_f64( +// CIR-LABEL: @vfmsq_f64( +float64x2_t test_vfmsq_f64(float64x2_t a, float64x2_t b, float64x2_t c) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<2 x !cir.double> +// CIR: cir.call @vfmaq_f64(%{{.*}}, [[NEG]], %{{.*}}) : + +// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]], <2 x double> {{.*}} [[B:%.*]], <2 x double> {{.*}} [[C:%.*]]) {{.*}} { +// LLVM: [[NEG:%.*]] = fneg <2 x double> [[B]] +// LLVM-NEXT: [[A_I:%.*]] = bitcast <2 x double> [[A]] to <2 x i64> +// LLVM-NEXT: [[B_I:%.*]] = bitcast <2 x double> [[NEG]] to <2 x i64> +// LLVM-NEXT: [[C_I:%.*]] = bitcast <2 x double> [[C]] to <2 x i64> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <2 x i64> [[A_I]] to <16 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <2 x i64> [[B_I]] to <16 x i8> +// LLVM-NEXT: [[C_BYTES:%.*]] = bitcast <2 x i64> [[C_I]] to <16 x i8> +// LLVM-NEXT: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_BYTES]] to <2 x double> +// LLVM-NEXT: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_BYTES]] to <2 x double> +// LLVM-NEXT: [[C_CAST:%.*]] = bitcast <16 x i8> [[C_BYTES]] to <2 x double> +// LLVM-NEXT: [[FMA:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> [[B_CAST]], <2 x double> [[C_CAST]], <2 x double> [[A_CAST]]) +// LLVM-NEXT: ret <2 x double> [[FMA]] + return vfmsq_f64(a, b, c); +} + >From 6fc9c58a45e371dd248f5f325a05b54973598b82 Mon Sep 17 00:00:00 2001 From: Yair Ben Avraham <[email protected]> Date: Wed, 1 Jul 2026 09:43:51 +0300 Subject: [PATCH 2/2] [CIR][AArch64] Move vfms lane tests Move the vfms lane and laneq coverage into neon/fused-multiply.c, including the scalar vfmss and vfmsd lane wrappers. The moved tests now run through direct LLVM, CIR-to-LLVM, and CIR paths; the superseded legacy checks are removed from neon-2velem.c and neon-scalar-x-indexed-elem.c. --- clang/test/CodeGen/AArch64/neon-2velem.c | 254 ------------ .../AArch64/neon-scalar-x-indexed-elem.c | 60 --- .../CodeGen/AArch64/neon/fused-multiply.c | 381 +++++++++++++++++- 3 files changed, 376 insertions(+), 319 deletions(-) diff --git a/clang/test/CodeGen/AArch64/neon-2velem.c b/clang/test/CodeGen/AArch64/neon-2velem.c index 273d8ce3cb316..fb572d69d013f 100644 --- a/clang/test/CodeGen/AArch64/neon-2velem.c +++ b/clang/test/CodeGen/AArch64/neon-2velem.c @@ -405,160 +405,6 @@ uint32x4_t test_vmulq_laneq_u32(uint32x4_t a, uint32x4_t v) { return vmulq_laneq_u32(a, v, 3); } -// CHECK-LABEL: @test_vfms_lane_f32( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A:%.*]] to <2 x i32> -// CHECK-NEXT: [[FNEG:%.*]] = fneg <2 x float> [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[FNEG]] to <2 x i32> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x float> [[V:%.*]] to <2 x i32> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <2 x i32> [[TMP2]] to <8 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP5]] to <2 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP6]], <2 x float> [[TMP6]], <2 x i32> <i32 1, i32 1> -// CHECK-NEXT: [[FMLA:%.*]] = bitcast <8 x i8> [[TMP4]] to <2 x float> -// CHECK-NEXT: [[FMLA1:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float> -// CHECK-NEXT: [[FMLA2:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[FMLA]], <2 x float> [[LANE]], <2 x float> [[FMLA1]]) -// CHECK-NEXT: ret <2 x float> [[FMLA2]] -// -float32x2_t test_vfms_lane_f32(float32x2_t a, float32x2_t b, float32x2_t v) { - return vfms_lane_f32(a, b, v, 1); -} - -// CHECK-LABEL: @test_vfmsq_lane_f32( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <4 x i32> -// CHECK-NEXT: [[FNEG:%.*]] = fneg <4 x float> [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[FNEG]] to <4 x i32> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x float> [[V:%.*]] to <2 x i32> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <2 x i32> [[TMP2]] to <8 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP5]] to <2 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP6]], <2 x float> [[TMP6]], <4 x i32> <i32 1, i32 1, i32 1, i32 1> -// CHECK-NEXT: [[FMLA:%.*]] = bitcast <16 x i8> [[TMP4]] to <4 x float> -// CHECK-NEXT: [[FMLA1:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float> -// CHECK-NEXT: [[FMLA2:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> [[FMLA]], <4 x float> [[LANE]], <4 x float> [[FMLA1]]) -// CHECK-NEXT: ret <4 x float> [[FMLA2]] -// -float32x4_t test_vfmsq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t v) { - return vfmsq_lane_f32(a, b, v, 1); -} - -// CHECK-LABEL: @test_vfms_laneq_f32( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A:%.*]] to <2 x i32> -// CHECK-NEXT: [[FNEG:%.*]] = fneg <2 x float> [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[FNEG]] to <2 x i32> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[V:%.*]] to <4 x i32> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <4 x i32> [[TMP2]] to <16 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <8 x i8> [[TMP4]] to <2 x float> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <4 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP8]], <4 x float> [[TMP8]], <2 x i32> <i32 3, i32 3> -// CHECK-NEXT: [[TMP9:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[LANE]], <2 x float> [[TMP7]], <2 x float> [[TMP6]]) -// CHECK-NEXT: ret <2 x float> [[TMP9]] -// -float32x2_t test_vfms_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t v) { - return vfms_laneq_f32(a, b, v, 3); -} - -// CHECK-LABEL: @test_vfmsq_laneq_f32( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <4 x i32> -// CHECK-NEXT: [[FNEG:%.*]] = fneg <4 x float> [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[FNEG]] to <4 x i32> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[V:%.*]] to <4 x i32> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <4 x i32> [[TMP2]] to <16 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <16 x i8> [[TMP4]] to <4 x float> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <4 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP8]], <4 x float> [[TMP8]], <4 x i32> <i32 3, i32 3, i32 3, i32 3> -// CHECK-NEXT: [[TMP9:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> [[LANE]], <4 x float> [[TMP7]], <4 x float> [[TMP6]]) -// CHECK-NEXT: ret <4 x float> [[TMP9]] -// -float32x4_t test_vfmsq_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t v) { - return vfmsq_laneq_f32(a, b, v, 3); -} - -// CHECK-LABEL: @test_vfmsq_lane_f64( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[A:%.*]] to <2 x i64> -// CHECK-NEXT: [[FNEG:%.*]] = fneg <2 x double> [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[FNEG]] to <2 x i64> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <1 x double> [[V:%.*]] to i64 -// CHECK-NEXT: [[__S2_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP2]], i32 0 -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <1 x i64> [[__S2_SROA_0_0_VEC_INSERT]] to <8 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP5]] to <1 x double> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <1 x double> [[TMP6]], <1 x double> [[TMP6]], <2 x i32> zeroinitializer -// CHECK-NEXT: [[FMLA:%.*]] = bitcast <16 x i8> [[TMP4]] to <2 x double> -// CHECK-NEXT: [[FMLA1:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double> -// CHECK-NEXT: [[FMLA2:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> [[FMLA]], <2 x double> [[LANE]], <2 x double> [[FMLA1]]) -// CHECK-NEXT: ret <2 x double> [[FMLA2]] -// -float64x2_t test_vfmsq_lane_f64(float64x2_t a, float64x2_t b, float64x1_t v) { - return vfmsq_lane_f64(a, b, v, 0); -} - -// CHECK-LABEL: @test_vfmsq_laneq_f64( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[A:%.*]] to <2 x i64> -// CHECK-NEXT: [[FNEG:%.*]] = fneg <2 x double> [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[FNEG]] to <2 x i64> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[V:%.*]] to <2 x i64> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <2 x i64> [[TMP2]] to <16 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <16 x i8> [[TMP4]] to <2 x double> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <2 x double> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x double> [[TMP8]], <2 x double> [[TMP8]], <2 x i32> <i32 1, i32 1> -// CHECK-NEXT: [[TMP9:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> [[LANE]], <2 x double> [[TMP7]], <2 x double> [[TMP6]]) -// CHECK-NEXT: ret <2 x double> [[TMP9]] -// -float64x2_t test_vfmsq_laneq_f64(float64x2_t a, float64x2_t b, float64x2_t v) { - return vfmsq_laneq_f64(a, b, v, 1); -} - -// CHECK-LABEL: @test_vfmsd_lane_f64( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[FNEG:%.*]] = fneg double [[B:%.*]] -// CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <1 x double> [[V:%.*]], i32 0 -// CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.fma.f64(double [[FNEG]], double [[EXTRACT]], double [[A:%.*]]) -// CHECK-NEXT: ret double [[TMP0]] -// -float64_t test_vfmsd_lane_f64(float64_t a, float64_t b, float64x1_t v) { - return vfmsd_lane_f64(a, b, v, 0); -} - -// CHECK-LABEL: @test_vfmss_laneq_f32( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[FNEG:%.*]] = fneg float [[B:%.*]] -// CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[V:%.*]], i32 3 -// CHECK-NEXT: [[TMP0:%.*]] = call float @llvm.fma.f32(float [[FNEG]], float [[EXTRACT]], float [[A:%.*]]) -// CHECK-NEXT: ret float [[TMP0]] -// -float32_t test_vfmss_laneq_f32(float32_t a, float32_t b, float32x4_t v) { - return vfmss_laneq_f32(a, b, v, 3); -} - -// CHECK-LABEL: @test_vfmsd_laneq_f64( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[FNEG:%.*]] = fneg double [[B:%.*]] -// CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <2 x double> [[V:%.*]], i32 1 -// CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.fma.f64(double [[FNEG]], double [[EXTRACT]], double [[A:%.*]]) -// CHECK-NEXT: ret double [[TMP0]] -// -float64_t test_vfmsd_laneq_f64(float64_t a, float64_t b, float64x2_t v) { - return vfmsd_laneq_f64(a, b, v, 1); -} - // CHECK-LABEL: @test_vmlal_lane_s16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[V:%.*]] to <8 x i8> @@ -2442,106 +2288,6 @@ float32x2_t test_vfma_lane_f32_0(float32x2_t a, float32x2_t b, float32x2_t v) { return vfma_lane_f32(a, b, v, 0); } -// CHECK-LABEL: @test_vfms_lane_f32_0( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A:%.*]] to <2 x i32> -// CHECK-NEXT: [[FNEG:%.*]] = fneg <2 x float> [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[FNEG]] to <2 x i32> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x float> [[V:%.*]] to <2 x i32> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <2 x i32> [[TMP2]] to <8 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP5]] to <2 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP6]], <2 x float> [[TMP6]], <2 x i32> zeroinitializer -// CHECK-NEXT: [[FMLA:%.*]] = bitcast <8 x i8> [[TMP4]] to <2 x float> -// CHECK-NEXT: [[FMLA1:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float> -// CHECK-NEXT: [[FMLA2:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[FMLA]], <2 x float> [[LANE]], <2 x float> [[FMLA1]]) -// CHECK-NEXT: ret <2 x float> [[FMLA2]] -// -float32x2_t test_vfms_lane_f32_0(float32x2_t a, float32x2_t b, float32x2_t v) { - return vfms_lane_f32(a, b, v, 0); -} - -// CHECK-LABEL: @test_vfmsq_lane_f32_0( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <4 x i32> -// CHECK-NEXT: [[FNEG:%.*]] = fneg <4 x float> [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[FNEG]] to <4 x i32> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x float> [[V:%.*]] to <2 x i32> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <2 x i32> [[TMP2]] to <8 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP5]] to <2 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP6]], <2 x float> [[TMP6]], <4 x i32> zeroinitializer -// CHECK-NEXT: [[FMLA:%.*]] = bitcast <16 x i8> [[TMP4]] to <4 x float> -// CHECK-NEXT: [[FMLA1:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float> -// CHECK-NEXT: [[FMLA2:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> [[FMLA]], <4 x float> [[LANE]], <4 x float> [[FMLA1]]) -// CHECK-NEXT: ret <4 x float> [[FMLA2]] -// -float32x4_t test_vfmsq_lane_f32_0(float32x4_t a, float32x4_t b, float32x2_t v) { - return vfmsq_lane_f32(a, b, v, 0); -} - -// CHECK-LABEL: @test_vfms_laneq_f32_0( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A:%.*]] to <2 x i32> -// CHECK-NEXT: [[FNEG:%.*]] = fneg <2 x float> [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[FNEG]] to <2 x i32> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[V:%.*]] to <4 x i32> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <4 x i32> [[TMP2]] to <16 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <8 x i8> [[TMP4]] to <2 x float> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <4 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP8]], <4 x float> [[TMP8]], <2 x i32> zeroinitializer -// CHECK-NEXT: [[TMP9:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[LANE]], <2 x float> [[TMP7]], <2 x float> [[TMP6]]) -// CHECK-NEXT: ret <2 x float> [[TMP9]] -// -float32x2_t test_vfms_laneq_f32_0(float32x2_t a, float32x2_t b, float32x4_t v) { - return vfms_laneq_f32(a, b, v, 0); -} - -// CHECK-LABEL: @test_vfmsq_laneq_f32_0( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <4 x i32> -// CHECK-NEXT: [[FNEG:%.*]] = fneg <4 x float> [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[FNEG]] to <4 x i32> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[V:%.*]] to <4 x i32> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <4 x i32> [[TMP2]] to <16 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <16 x i8> [[TMP4]] to <4 x float> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <4 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP8]], <4 x float> [[TMP8]], <4 x i32> zeroinitializer -// CHECK-NEXT: [[TMP9:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> [[LANE]], <4 x float> [[TMP7]], <4 x float> [[TMP6]]) -// CHECK-NEXT: ret <4 x float> [[TMP9]] -// -float32x4_t test_vfmsq_laneq_f32_0(float32x4_t a, float32x4_t b, float32x4_t v) { - return vfmsq_laneq_f32(a, b, v, 0); -} - -// CHECK-LABEL: @test_vfmsq_laneq_f64_0( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[A:%.*]] to <2 x i64> -// CHECK-NEXT: [[FNEG:%.*]] = fneg <2 x double> [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[FNEG]] to <2 x i64> -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[V:%.*]] to <2 x i64> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <2 x i64> [[TMP2]] to <16 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <16 x i8> [[TMP4]] to <2 x double> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <2 x double> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x double> [[TMP8]], <2 x double> [[TMP8]], <2 x i32> zeroinitializer -// CHECK-NEXT: [[TMP9:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> [[LANE]], <2 x double> [[TMP7]], <2 x double> [[TMP6]]) -// CHECK-NEXT: ret <2 x double> [[TMP9]] -// -float64x2_t test_vfmsq_laneq_f64_0(float64x2_t a, float64x2_t b, float64x2_t v) { - return vfmsq_laneq_f64(a, b, v, 0); -} - // CHECK-LABEL: @test_vmlal_lane_s16_0( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[V:%.*]] to <8 x i8> diff --git a/clang/test/CodeGen/AArch64/neon-scalar-x-indexed-elem.c b/clang/test/CodeGen/AArch64/neon-scalar-x-indexed-elem.c index f701fbf4132e8..7719281e9f10f 100644 --- a/clang/test/CodeGen/AArch64/neon-scalar-x-indexed-elem.c +++ b/clang/test/CodeGen/AArch64/neon-scalar-x-indexed-elem.c @@ -148,66 +148,6 @@ float64x1_t test_vmulx_laneq_f64_1(float64x1_t a, float64x2_t b) { } -// CHECK-LABEL: define dso_local float @test_vfmss_lane_f32( -// CHECK-SAME: float noundef [[A:%.*]], float noundef [[B:%.*]], <2 x float> noundef [[C:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[FNEG:%.*]] = fneg float [[B]] -// CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <2 x float> [[C]], i32 1 -// CHECK-NEXT: [[TMP0:%.*]] = call float @llvm.fma.f32(float [[FNEG]], float [[EXTRACT]], float [[A]]) -// CHECK-NEXT: ret float [[TMP0]] -// -float32_t test_vfmss_lane_f32(float32_t a, float32_t b, float32x2_t c) { - return vfmss_lane_f32(a, b, c, 1); -} - -// CHECK-LABEL: define dso_local <1 x double> @test_vfms_lane_f64( -// CHECK-SAME: <1 x double> noundef [[A:%.*]], <1 x double> noundef [[B:%.*]], <1 x double> noundef [[V:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x double> [[A]] to i64 -// CHECK-NEXT: [[__S0_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP0]], i32 0 -// CHECK-NEXT: [[FNEG:%.*]] = fneg <1 x double> [[B]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <1 x double> [[FNEG]] to i64 -// CHECK-NEXT: [[__S1_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP1]], i32 0 -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <1 x double> [[V]] to i64 -// CHECK-NEXT: [[__S2_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP2]], i32 0 -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <1 x i64> [[__S0_SROA_0_0_VEC_INSERT]] to <8 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <1 x i64> [[__S1_SROA_0_0_VEC_INSERT]] to <8 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <1 x i64> [[__S2_SROA_0_0_VEC_INSERT]] to <8 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP5]] to <1 x double> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <1 x double> [[TMP6]], <1 x double> [[TMP6]], <1 x i32> zeroinitializer -// CHECK-NEXT: [[FMLA:%.*]] = bitcast <8 x i8> [[TMP4]] to <1 x double> -// CHECK-NEXT: [[FMLA1:%.*]] = bitcast <8 x i8> [[TMP3]] to <1 x double> -// CHECK-NEXT: [[FMLA2:%.*]] = call <1 x double> @llvm.fma.v1f64(<1 x double> [[FMLA]], <1 x double> [[LANE]], <1 x double> [[FMLA1]]) -// CHECK-NEXT: ret <1 x double> [[FMLA2]] -// -float64x1_t test_vfms_lane_f64(float64x1_t a, float64x1_t b, float64x1_t v) { - return vfms_lane_f64(a, b, v, 0); -} - -// CHECK-LABEL: define dso_local <1 x double> @test_vfms_laneq_f64( -// CHECK-SAME: <1 x double> noundef [[A:%.*]], <1 x double> noundef [[B:%.*]], <2 x double> noundef [[V:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x double> [[A]] to i64 -// CHECK-NEXT: [[__S0_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP0]], i32 0 -// CHECK-NEXT: [[FNEG:%.*]] = fneg <1 x double> [[B]] -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <1 x double> [[FNEG]] to i64 -// CHECK-NEXT: [[__S1_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP1]], i32 0 -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[V]] to <2 x i64> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <1 x i64> [[__S0_SROA_0_0_VEC_INSERT]] to <8 x i8> -// CHECK-NEXT: [[TMP4:%.*]] = bitcast <1 x i64> [[__S1_SROA_0_0_VEC_INSERT]] to <8 x i8> -// CHECK-NEXT: [[TMP5:%.*]] = bitcast <2 x i64> [[TMP2]] to <16 x i8> -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x i8> [[TMP3]] to double -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <8 x i8> [[TMP4]] to double -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <16 x i8> [[TMP5]] to <2 x double> -// CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <2 x double> [[TMP8]], i32 0 -// CHECK-NEXT: [[TMP9:%.*]] = call double @llvm.fma.f64(double [[TMP7]], double [[EXTRACT]], double [[TMP6]]) -// CHECK-NEXT: [[TMP10:%.*]] = bitcast double [[TMP9]] to <1 x double> -// CHECK-NEXT: ret <1 x double> [[TMP10]] -// -float64x1_t test_vfms_laneq_f64(float64x1_t a, float64x1_t b, float64x2_t v) { - return vfms_laneq_f64(a, b, v, 0); -} - // CHECK-LABEL: define dso_local i32 @test_vqdmullh_lane_s16( // CHECK-SAME: i16 noundef [[A:%.*]], <4 x i16> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] diff --git a/clang/test/CodeGen/AArch64/neon/fused-multiply.c b/clang/test/CodeGen/AArch64/neon/fused-multiply.c index ba1219b424576..2328ead2568df 100644 --- a/clang/test/CodeGen/AArch64/neon/fused-multiply.c +++ b/clang/test/CodeGen/AArch64/neon/fused-multiply.c @@ -11,13 +11,12 @@ // // This file contains tests that were originally located in: // * clang/test/CodeGen/AArch64/neon-intrinsics.c +// * clang/test/CodeGen/AArch64/neon-2velem.c // * clang/test/CodeGen/AArch64/neon-scalar-x-indexed-elem.c // The main difference is the use of RUN lines that enable ClangIR lowering. -// This file currently covers the f32/f64 wrappers that lower through -// BI__builtin_neon_vfmaq_v, BI__builtin_neon_vfmaq_lane_v, -// BI__builtin_neon_vfma_laneq_v, BI__builtin_neon_vfmaq_laneq_v, -// BI__builtin_neon_vfmad_lane_f64, and -// BI__builtin_neon_vfmad_laneq_f64. +// This file currently covers the f32/f64 fused multiply-accumulate and fused +// multiply-subtract wrappers, including the vfma/vfmaq/vfmas/vfmad and +// vfms/vfmsq/vfmss/vfmsd vector, lane, laneq, and scalar-lane forms. // // ACLE section headings based on v2025Q2 of the ACLE specification: // * https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#fused-multiply-accumulate @@ -500,3 +499,375 @@ float64x2_t test_vfmsq_f64(float64x2_t a, float64x2_t b, float64x2_t c) { return vfmsq_f64(a, b, c); } +// ALL-LABEL: @test_vfms_lane_f32( +float32x2_t test_vfms_lane_f32(float32x2_t a, float32x2_t b, float32x2_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<2 x !cir.float> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<2 x !cir.float>) [#cir.int<1> : !s32i, #cir.int<1> : !s32i] : !cir.vector<2 x !cir.float> +// CIR: cir.call_llvm_intrinsic "fma" %{{.*}}, [[LANE]], %{{.*}} : (!cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>) -> !cir.vector<2 x !cir.float> + +// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]], <2 x float> {{.*}} [[B:%.*]], <2 x float> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <2 x float> [[A]] to <2 x i32> +// LLVM-NEXT: [[NEG:%.*]] = fneg <2 x float> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <2 x float> [[NEG]] to <2 x i32> +// LLVM-NEXT: [[V_I:%.*]] = bitcast <2 x float> [[V]] to <2 x i32> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <2 x i32> [[A_I]] to <8 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <2 x i32> [[B_I]] to <8 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <2 x i32> [[V_I]] to <8 x i8> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <8 x i8> [[V_BYTES]] to <2 x float> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_BYTES]] to <2 x float> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_BYTES]] to <2 x float> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <2 x float> [[V_CAST]], <2 x float> {{.*}}, <2 x i32> <i32 1, i32 1> +// LLVM: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[B_CAST]], <2 x float> [[LANE]], <2 x float> [[A_CAST]]) +// LLVM: ret <2 x float> [[FMA]] + return vfms_lane_f32(a, b, v, 1); +} + +// ALL-LABEL: @test_vfms_lane_f64( +float64x1_t test_vfms_lane_f64(float64x1_t a, float64x1_t b, float64x1_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<1 x !cir.double> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<1 x !cir.double>) [#cir.int<0> : !s32i] : !cir.vector<1 x !cir.double> +// CIR: cir.call_llvm_intrinsic "fma" %{{.*}}, [[LANE]], %{{.*}} : (!cir.vector<1 x !cir.double>, !cir.vector<1 x !cir.double>, !cir.vector<1 x !cir.double>) -> !cir.vector<1 x !cir.double> + +// LLVM-SAME: <1 x double> {{.*}} [[A:%.*]], <1 x double> {{.*}} [[B:%.*]], <1 x double> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <1 x double> [[A]] to i64 +// LLVM-NEXT: [[A_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[A_I]], i32 0 +// LLVM-NEXT: [[NEG:%.*]] = fneg <1 x double> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <1 x double> [[NEG]] to i64 +// LLVM-NEXT: [[B_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[B_I]], i32 0 +// LLVM-NEXT: [[V_I:%.*]] = bitcast <1 x double> [[V]] to i64 +// LLVM-NEXT: [[V_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[V_I]], i32 0 +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <1 x i64> [[A_INSERT]] to <8 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <1 x i64> [[B_INSERT]] to <8 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <1 x i64> [[V_INSERT]] to <8 x i8> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <8 x i8> [[V_BYTES]] to <1 x double> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_BYTES]] to <1 x double> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_BYTES]] to <1 x double> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <1 x double> [[V_CAST]], <1 x double> {{.*}}, <1 x i32> zeroinitializer +// LLVM: [[FMA:%.*]] = call <1 x double> @llvm.fma.v1f64(<1 x double> [[B_CAST]], <1 x double> [[LANE]], <1 x double> [[A_CAST]]) +// LLVM: ret <1 x double> [[FMA]] + return vfms_lane_f64(a, b, v, 0); +} + +// ALL-LABEL: @test_vfms_lane_f32_0( +float32x2_t test_vfms_lane_f32_0(float32x2_t a, float32x2_t b, + float32x2_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<2 x !cir.float> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<2 x !cir.float>) [#cir.int<0> : !s32i, #cir.int<0> : !s32i] : !cir.vector<2 x !cir.float> +// CIR: cir.call_llvm_intrinsic "fma" %{{.*}}, [[LANE]], %{{.*}} : (!cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>) -> !cir.vector<2 x !cir.float> + +// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]], <2 x float> {{.*}} [[B:%.*]], <2 x float> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <2 x float> [[A]] to <2 x i32> +// LLVM-NEXT: [[NEG:%.*]] = fneg <2 x float> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <2 x float> [[NEG]] to <2 x i32> +// LLVM-NEXT: [[V_I:%.*]] = bitcast <2 x float> [[V]] to <2 x i32> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <2 x i32> [[A_I]] to <8 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <2 x i32> [[B_I]] to <8 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <2 x i32> [[V_I]] to <8 x i8> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <8 x i8> [[V_BYTES]] to <2 x float> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_BYTES]] to <2 x float> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_BYTES]] to <2 x float> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <2 x float> [[V_CAST]], <2 x float> {{.*}}, <2 x i32> zeroinitializer +// LLVM: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[B_CAST]], <2 x float> [[LANE]], <2 x float> [[A_CAST]]) +// LLVM: ret <2 x float> [[FMA]] + return vfms_lane_f32(a, b, v, 0); +} + +// ALL-LABEL: @test_vfmsq_lane_f32( +float32x4_t test_vfmsq_lane_f32(float32x4_t a, float32x4_t b, + float32x2_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<4 x !cir.float> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<2 x !cir.float>) [#cir.int<1> : !s32i, #cir.int<1> : !s32i, #cir.int<1> : !s32i, #cir.int<1> : !s32i] : !cir.vector<4 x !cir.float> +// CIR: cir.call_llvm_intrinsic "fma" %{{.*}}, [[LANE]], %{{.*}} : (!cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>) -> !cir.vector<4 x !cir.float> + +// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]], <4 x float> {{.*}} [[B:%.*]], <2 x float> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <4 x float> [[A]] to <4 x i32> +// LLVM-NEXT: [[NEG:%.*]] = fneg <4 x float> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <4 x float> [[NEG]] to <4 x i32> +// LLVM-NEXT: [[V_I:%.*]] = bitcast <2 x float> [[V]] to <2 x i32> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <4 x i32> [[A_I]] to <16 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <4 x i32> [[B_I]] to <16 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <2 x i32> [[V_I]] to <8 x i8> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <8 x i8> [[V_BYTES]] to <2 x float> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_BYTES]] to <4 x float> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_BYTES]] to <4 x float> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <2 x float> [[V_CAST]], <2 x float> {{.*}}, <4 x i32> <i32 1, i32 1, i32 1, i32 1> +// LLVM: [[FMA:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> [[B_CAST]], <4 x float> [[LANE]], <4 x float> [[A_CAST]]) +// LLVM: ret <4 x float> [[FMA]] + return vfmsq_lane_f32(a, b, v, 1); +} + +// ALL-LABEL: @test_vfmsq_lane_f64( +float64x2_t test_vfmsq_lane_f64(float64x2_t a, float64x2_t b, + float64x1_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<2 x !cir.double> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<1 x !cir.double>) [#cir.int<0> : !s32i, #cir.int<0> : !s32i] : !cir.vector<2 x !cir.double> +// CIR: cir.call_llvm_intrinsic "fma" %{{.*}}, [[LANE]], %{{.*}} : (!cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>) -> !cir.vector<2 x !cir.double> + +// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]], <2 x double> {{.*}} [[B:%.*]], <1 x double> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <2 x double> [[A]] to <2 x i64> +// LLVM-NEXT: [[NEG:%.*]] = fneg <2 x double> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <2 x double> [[NEG]] to <2 x i64> +// LLVM-NEXT: [[V_I:%.*]] = bitcast <1 x double> [[V]] to i64 +// LLVM-NEXT: [[V_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[V_I]], i32 0 +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <2 x i64> [[A_I]] to <16 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <2 x i64> [[B_I]] to <16 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <1 x i64> [[V_INSERT]] to <8 x i8> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <8 x i8> [[V_BYTES]] to <1 x double> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_BYTES]] to <2 x double> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_BYTES]] to <2 x double> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <1 x double> [[V_CAST]], <1 x double> {{.*}}, <2 x i32> zeroinitializer +// LLVM: [[FMA:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> [[B_CAST]], <2 x double> [[LANE]], <2 x double> [[A_CAST]]) +// LLVM: ret <2 x double> [[FMA]] + return vfmsq_lane_f64(a, b, v, 0); +} + +// ALL-LABEL: @test_vfmsq_lane_f32_0( +float32x4_t test_vfmsq_lane_f32_0(float32x4_t a, float32x4_t b, + float32x2_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<4 x !cir.float> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<2 x !cir.float>) [#cir.int<0> : !s32i, #cir.int<0> : !s32i, #cir.int<0> : !s32i, #cir.int<0> : !s32i] : !cir.vector<4 x !cir.float> +// CIR: cir.call_llvm_intrinsic "fma" %{{.*}}, [[LANE]], %{{.*}} : (!cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>) -> !cir.vector<4 x !cir.float> + +// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]], <4 x float> {{.*}} [[B:%.*]], <2 x float> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <4 x float> [[A]] to <4 x i32> +// LLVM-NEXT: [[NEG:%.*]] = fneg <4 x float> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <4 x float> [[NEG]] to <4 x i32> +// LLVM-NEXT: [[V_I:%.*]] = bitcast <2 x float> [[V]] to <2 x i32> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <4 x i32> [[A_I]] to <16 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <4 x i32> [[B_I]] to <16 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <2 x i32> [[V_I]] to <8 x i8> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <8 x i8> [[V_BYTES]] to <2 x float> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_BYTES]] to <4 x float> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_BYTES]] to <4 x float> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <2 x float> [[V_CAST]], <2 x float> {{.*}}, <4 x i32> zeroinitializer +// LLVM: [[FMA:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> [[B_CAST]], <4 x float> [[LANE]], <4 x float> [[A_CAST]]) +// LLVM: ret <4 x float> [[FMA]] + return vfmsq_lane_f32(a, b, v, 0); +} + +// ALL-LABEL: @test_vfms_laneq_f32( +float32x2_t test_vfms_laneq_f32(float32x2_t a, float32x2_t b, + float32x4_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<2 x !cir.float> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<4 x !cir.float>) [#cir.int<3> : !s32i, #cir.int<3> : !s32i] : !cir.vector<2 x !cir.float> +// CIR: cir.call_llvm_intrinsic "fma" [[LANE]], %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>) -> !cir.vector<2 x !cir.float> + +// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]], <2 x float> {{.*}} [[B:%.*]], <4 x float> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <2 x float> [[A]] to <2 x i32> +// LLVM-NEXT: [[NEG:%.*]] = fneg <2 x float> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <2 x float> [[NEG]] to <2 x i32> +// LLVM-NEXT: [[V_I:%.*]] = bitcast <4 x float> [[V]] to <4 x i32> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <2 x i32> [[A_I]] to <8 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <2 x i32> [[B_I]] to <8 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <4 x i32> [[V_I]] to <16 x i8> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_BYTES]] to <2 x float> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_BYTES]] to <2 x float> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <16 x i8> [[V_BYTES]] to <4 x float> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <4 x float> [[V_CAST]], <4 x float> {{.*}}, <2 x i32> <i32 3, i32 3> +// LLVM: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[LANE]], <2 x float> [[B_CAST]], <2 x float> [[A_CAST]]) +// LLVM: ret <2 x float> [[FMA]] + return vfms_laneq_f32(a, b, v, 3); +} + +// ALL-LABEL: @test_vfms_laneq_f64( +float64x1_t test_vfms_laneq_f64(float64x1_t a, float64x1_t b, + float64x2_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<1 x !cir.double> +// CIR: [[LANE:%.*]] = cir.vec.extract %{{.*}}[%{{.*}} : !u64i] : !cir.vector<2 x !cir.double> +// CIR: cir.call_llvm_intrinsic "fma" %{{.*}}, [[LANE]], %{{.*}} : (!cir.double, !cir.double, !cir.double) -> !cir.double + +// LLVM-SAME: <1 x double> {{.*}} [[A:%.*]], <1 x double> {{.*}} [[B:%.*]], <2 x double> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <1 x double> [[A]] to i64 +// LLVM-NEXT: [[A_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[A_I]], i32 0 +// LLVM-NEXT: [[NEG:%.*]] = fneg <1 x double> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <1 x double> [[NEG]] to i64 +// LLVM-NEXT: [[B_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[B_I]], i32 0 +// LLVM-NEXT: [[V_I:%.*]] = bitcast <2 x double> [[V]] to <2 x i64> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <1 x i64> [[A_INSERT]] to <8 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <1 x i64> [[B_INSERT]] to <8 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <2 x i64> [[V_I]] to <16 x i8> +// LLVM-NEXT: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_BYTES]] to double +// LLVM-NEXT: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_BYTES]] to double +// LLVM-NEXT: [[V_CAST:%.*]] = bitcast <16 x i8> [[V_BYTES]] to <2 x double> +// LLVM-NEXT: [[LANE:%.*]] = extractelement <2 x double> [[V_CAST]], i{{32|64}} 0 +// LLVM-NEXT: [[FMA:%.*]] = call double @llvm.fma.f64(double [[B_CAST]], double [[LANE]], double [[A_CAST]]) +// LLVM-NEXT: [[RET:%.*]] = bitcast double [[FMA]] to <1 x double> +// LLVM: ret <1 x double> [[RET]] + return vfms_laneq_f64(a, b, v, 0); +} + +// ALL-LABEL: @test_vfms_laneq_f32_0( +float32x2_t test_vfms_laneq_f32_0(float32x2_t a, float32x2_t b, + float32x4_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<2 x !cir.float> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<4 x !cir.float>) [#cir.int<0> : !s32i, #cir.int<0> : !s32i] : !cir.vector<2 x !cir.float> +// CIR: cir.call_llvm_intrinsic "fma" [[LANE]], %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>) -> !cir.vector<2 x !cir.float> + +// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]], <2 x float> {{.*}} [[B:%.*]], <4 x float> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <2 x float> [[A]] to <2 x i32> +// LLVM-NEXT: [[NEG:%.*]] = fneg <2 x float> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <2 x float> [[NEG]] to <2 x i32> +// LLVM-NEXT: [[V_I:%.*]] = bitcast <4 x float> [[V]] to <4 x i32> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <2 x i32> [[A_I]] to <8 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <2 x i32> [[B_I]] to <8 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <4 x i32> [[V_I]] to <16 x i8> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_BYTES]] to <2 x float> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_BYTES]] to <2 x float> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <16 x i8> [[V_BYTES]] to <4 x float> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <4 x float> [[V_CAST]], <4 x float> {{.*}}, <2 x i32> zeroinitializer +// LLVM: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[LANE]], <2 x float> [[B_CAST]], <2 x float> [[A_CAST]]) +// LLVM: ret <2 x float> [[FMA]] + return vfms_laneq_f32(a, b, v, 0); +} + +// ALL-LABEL: @test_vfmsq_laneq_f32( +float32x4_t test_vfmsq_laneq_f32(float32x4_t a, float32x4_t b, + float32x4_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<4 x !cir.float> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<4 x !cir.float>) [#cir.int<3> : !s32i, #cir.int<3> : !s32i, #cir.int<3> : !s32i, #cir.int<3> : !s32i] : !cir.vector<4 x !cir.float> +// CIR: cir.call_llvm_intrinsic "fma" [[LANE]], %{{.*}}, %{{.*}} : (!cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>) -> !cir.vector<4 x !cir.float> + +// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]], <4 x float> {{.*}} [[B:%.*]], <4 x float> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <4 x float> [[A]] to <4 x i32> +// LLVM-NEXT: [[NEG:%.*]] = fneg <4 x float> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <4 x float> [[NEG]] to <4 x i32> +// LLVM-NEXT: [[V_I:%.*]] = bitcast <4 x float> [[V]] to <4 x i32> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <4 x i32> [[A_I]] to <16 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <4 x i32> [[B_I]] to <16 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <4 x i32> [[V_I]] to <16 x i8> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_BYTES]] to <4 x float> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_BYTES]] to <4 x float> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <16 x i8> [[V_BYTES]] to <4 x float> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <4 x float> [[V_CAST]], <4 x float> {{.*}}, <4 x i32> <i32 3, i32 3, i32 3, i32 3> +// LLVM: [[FMA:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> [[LANE]], <4 x float> [[B_CAST]], <4 x float> [[A_CAST]]) +// LLVM: ret <4 x float> [[FMA]] + return vfmsq_laneq_f32(a, b, v, 3); +} + +// ALL-LABEL: @test_vfmsq_laneq_f64( +float64x2_t test_vfmsq_laneq_f64(float64x2_t a, float64x2_t b, + float64x2_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<2 x !cir.double> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<2 x !cir.double>) [#cir.int<1> : !s32i, #cir.int<1> : !s32i] : !cir.vector<2 x !cir.double> +// CIR: cir.call_llvm_intrinsic "fma" [[LANE]], %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>) -> !cir.vector<2 x !cir.double> + +// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]], <2 x double> {{.*}} [[B:%.*]], <2 x double> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <2 x double> [[A]] to <2 x i64> +// LLVM-NEXT: [[NEG:%.*]] = fneg <2 x double> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <2 x double> [[NEG]] to <2 x i64> +// LLVM-NEXT: [[V_I:%.*]] = bitcast <2 x double> [[V]] to <2 x i64> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <2 x i64> [[A_I]] to <16 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <2 x i64> [[B_I]] to <16 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <2 x i64> [[V_I]] to <16 x i8> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_BYTES]] to <2 x double> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_BYTES]] to <2 x double> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <16 x i8> [[V_BYTES]] to <2 x double> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <2 x double> [[V_CAST]], <2 x double> {{.*}}, <2 x i32> <i32 1, i32 1> +// LLVM: [[FMA:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> [[LANE]], <2 x double> [[B_CAST]], <2 x double> [[A_CAST]]) +// LLVM: ret <2 x double> [[FMA]] + return vfmsq_laneq_f64(a, b, v, 1); +} + +// ALL-LABEL: @test_vfmsq_laneq_f32_0( +float32x4_t test_vfmsq_laneq_f32_0(float32x4_t a, float32x4_t b, + float32x4_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<4 x !cir.float> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<4 x !cir.float>) [#cir.int<0> : !s32i, #cir.int<0> : !s32i, #cir.int<0> : !s32i, #cir.int<0> : !s32i] : !cir.vector<4 x !cir.float> +// CIR: cir.call_llvm_intrinsic "fma" [[LANE]], %{{.*}}, %{{.*}} : (!cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>) -> !cir.vector<4 x !cir.float> + +// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]], <4 x float> {{.*}} [[B:%.*]], <4 x float> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <4 x float> [[A]] to <4 x i32> +// LLVM-NEXT: [[NEG:%.*]] = fneg <4 x float> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <4 x float> [[NEG]] to <4 x i32> +// LLVM-NEXT: [[V_I:%.*]] = bitcast <4 x float> [[V]] to <4 x i32> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <4 x i32> [[A_I]] to <16 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <4 x i32> [[B_I]] to <16 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <4 x i32> [[V_I]] to <16 x i8> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_BYTES]] to <4 x float> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_BYTES]] to <4 x float> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <16 x i8> [[V_BYTES]] to <4 x float> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <4 x float> [[V_CAST]], <4 x float> {{.*}}, <4 x i32> zeroinitializer +// LLVM: [[FMA:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> [[LANE]], <4 x float> [[B_CAST]], <4 x float> [[A_CAST]]) +// LLVM: ret <4 x float> [[FMA]] + return vfmsq_laneq_f32(a, b, v, 0); +} + +// ALL-LABEL: @test_vfmsq_laneq_f64_0( +float64x2_t test_vfmsq_laneq_f64_0(float64x2_t a, float64x2_t b, + float64x2_t v) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.vector<2 x !cir.double> +// CIR: [[LANE:%.*]] = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<2 x !cir.double>) [#cir.int<0> : !s32i, #cir.int<0> : !s32i] : !cir.vector<2 x !cir.double> +// CIR: cir.call_llvm_intrinsic "fma" [[LANE]], %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>) -> !cir.vector<2 x !cir.double> + +// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]], <2 x double> {{.*}} [[B:%.*]], <2 x double> {{.*}} [[V:%.*]]) {{.*}} { +// LLVM: [[A_I:%.*]] = bitcast <2 x double> [[A]] to <2 x i64> +// LLVM-NEXT: [[NEG:%.*]] = fneg <2 x double> [[B]] +// LLVM-NEXT: [[B_I:%.*]] = bitcast <2 x double> [[NEG]] to <2 x i64> +// LLVM-NEXT: [[V_I:%.*]] = bitcast <2 x double> [[V]] to <2 x i64> +// LLVM-NEXT: [[A_BYTES:%.*]] = bitcast <2 x i64> [[A_I]] to <16 x i8> +// LLVM-NEXT: [[B_BYTES:%.*]] = bitcast <2 x i64> [[B_I]] to <16 x i8> +// LLVM-NEXT: [[V_BYTES:%.*]] = bitcast <2 x i64> [[V_I]] to <16 x i8> +// LLVM-DAG: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_BYTES]] to <2 x double> +// LLVM-DAG: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_BYTES]] to <2 x double> +// LLVM-DAG: [[V_CAST:%.*]] = bitcast <16 x i8> [[V_BYTES]] to <2 x double> +// LLVM-DAG: [[LANE:%.*]] = shufflevector <2 x double> [[V_CAST]], <2 x double> {{.*}}, <2 x i32> zeroinitializer +// LLVM: [[FMA:%.*]] = call <2 x double> @llvm.fma.v2f64(<2 x double> [[LANE]], <2 x double> [[B_CAST]], <2 x double> [[A_CAST]]) +// LLVM: ret <2 x double> [[FMA]] + return vfmsq_laneq_f64(a, b, v, 0); +} + +// ALL-LABEL: @test_vfmss_lane_f32( +float32_t test_vfmss_lane_f32(float32_t a, float32_t b, float32x2_t c) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.float +// CIR: [[LANE:%.*]] = cir.vec.extract %{{.*}}[%{{.*}} : !u64i] : !cir.vector<2 x !cir.float> +// CIR: cir.call_llvm_intrinsic "fma" %{{.*}}, [[LANE]], %{{.*}} : (!cir.float, !cir.float, !cir.float) -> !cir.float + +// LLVM-SAME: float {{.*}} [[A:%.*]], float {{.*}} [[B:%.*]], <2 x float> {{.*}} [[C:%.*]]) {{.*}} { +// LLVM: [[NEG:%.*]] = fneg float [[B]] +// LLVM: [[LANE:%.*]] = extractelement <2 x float> [[C]], i{{32|64}} 1 +// LLVM: [[FMA:%.*]] = call float @llvm.fma.f32(float [[NEG]], float [[LANE]], float [[A]]) +// LLVM: ret float [[FMA]] + return vfmss_lane_f32(a, b, c, 1); +} + +// ALL-LABEL: @test_vfmss_laneq_f32( +float32_t test_vfmss_laneq_f32(float32_t a, float32_t b, float32x4_t c) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.float +// CIR: [[LANE:%.*]] = cir.vec.extract %{{.*}}[%{{.*}} : !u64i] : !cir.vector<4 x !cir.float> +// CIR: cir.call_llvm_intrinsic "fma" %{{.*}}, [[LANE]], %{{.*}} : (!cir.float, !cir.float, !cir.float) -> !cir.float + +// LLVM-SAME: float {{.*}} [[A:%.*]], float {{.*}} [[B:%.*]], <4 x float> {{.*}} [[C:%.*]]) {{.*}} { +// LLVM: [[NEG:%.*]] = fneg float [[B]] +// LLVM: [[LANE:%.*]] = extractelement <4 x float> [[C]], i{{32|64}} 3 +// LLVM: [[FMA:%.*]] = call float @llvm.fma.f32(float [[NEG]], float [[LANE]], float [[A]]) +// LLVM: ret float [[FMA]] + return vfmss_laneq_f32(a, b, c, 3); +} + +// ALL-LABEL: @test_vfmsd_lane_f64( +float64_t test_vfmsd_lane_f64(float64_t a, float64_t b, float64x1_t c) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.double +// CIR: [[LANE:%.*]] = cir.vec.extract %{{.*}}[%{{.*}} : !u64i] : !cir.vector<1 x !cir.double> +// CIR: cir.call_llvm_intrinsic "fma" %{{.*}}, [[LANE]], %{{.*}} : (!cir.double, !cir.double, !cir.double) -> !cir.double + +// LLVM-SAME: double {{.*}} [[A:%.*]], double {{.*}} [[B:%.*]], <1 x double> {{.*}} [[C:%.*]]) {{.*}} { +// LLVM: [[NEG:%.*]] = fneg double [[B]] +// LLVM: [[LANE:%.*]] = extractelement <1 x double> [[C]], i{{32|64}} 0 +// LLVM: [[FMA:%.*]] = call double @llvm.fma.f64(double [[NEG]], double [[LANE]], double [[A]]) +// LLVM: ret double [[FMA]] + return vfmsd_lane_f64(a, b, c, 0); +} + +// ALL-LABEL: @test_vfmsd_laneq_f64( +float64_t test_vfmsd_laneq_f64(float64_t a, float64_t b, float64x2_t c) { +// CIR: [[NEG:%.*]] = cir.fneg %{{.*}} : !cir.double +// CIR: [[LANE:%.*]] = cir.vec.extract %{{.*}}[%{{.*}} : !u64i] : !cir.vector<2 x !cir.double> +// CIR: cir.call_llvm_intrinsic "fma" %{{.*}}, [[LANE]], %{{.*}} : (!cir.double, !cir.double, !cir.double) -> !cir.double + +// LLVM-SAME: double {{.*}} [[A:%.*]], double {{.*}} [[B:%.*]], <2 x double> {{.*}} [[C:%.*]]) {{.*}} { +// LLVM: [[NEG:%.*]] = fneg double [[B]] +// LLVM: [[LANE:%.*]] = extractelement <2 x double> [[C]], i{{32|64}} 1 +// LLVM: [[FMA:%.*]] = call double @llvm.fma.f64(double [[NEG]], double [[LANE]], double [[A]]) +// LLVM: ret double [[FMA]] + return vfmsd_laneq_f64(a, b, c, 1); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
