Skip to content

Commit 67d71bb

Browse files
authored
[CIR][CIRGen][Builtin][Neon] Lower neon_vaddv_f32, neon_vaddvq_f32 and neon_vaddvq_f64 (#1238)
[Neon intrinsic definition](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_f32). They are vector across operation which LLVM doesn't currently have a generic intrinsic about it. As a side note for brainstorm, it might be worth in the future for CIR to introduce Vector Across type operations even though LLVM dialect doesn't have it yet. This would help to expose opt opportunities. E.g. a very trivial constant fold can happen if we are adding across a constant vector.
1 parent d3193f8 commit 67d71bb

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -2678,16 +2678,15 @@ static mlir::Value emitCommonNeonSISDBuiltinExpr(
26782678
case NEON::BI__builtin_neon_vaddlvq_u32:
26792679
return emitNeonCall(builder, {argTy}, ops, "aarch64.neon.uaddlv", resultTy,
26802680
loc);
2681-
case NEON::BI__builtin_neon_vaddv_f32:
2682-
llvm_unreachable(" neon_vaddv_f32 NYI ");
26832681
case NEON::BI__builtin_neon_vaddv_s32:
26842682
llvm_unreachable(" neon_vaddv_s32 NYI ");
26852683
case NEON::BI__builtin_neon_vaddv_u32:
26862684
llvm_unreachable(" neon_vaddv_u32 NYI ");
2685+
case NEON::BI__builtin_neon_vaddv_f32:
26872686
case NEON::BI__builtin_neon_vaddvq_f32:
2688-
llvm_unreachable(" neon_vaddvq_f32 NYI ");
26892687
case NEON::BI__builtin_neon_vaddvq_f64:
2690-
llvm_unreachable(" neon_vaddvq_f64 NYI ");
2688+
return emitNeonCall(builder, {argTy}, ops, "aarch64.neon.faddv", resultTy,
2689+
loc);
26912690
case NEON::BI__builtin_neon_vaddvq_s32:
26922691
llvm_unreachable(" neon_vaddvq_s32 NYI ");
26932692
case NEON::BI__builtin_neon_vaddvq_s64:

clang/test/CIR/CodeGen/AArch64/neon.c

+33-18
Original file line numberDiff line numberDiff line change
@@ -18383,26 +18383,41 @@ uint64x1_t test_vrsra_n_u64(uint64x1_t a, uint64x1_t b) {
1838318383
// return vneg_s64(a);
1838418384
// }
1838518385

18386-
// NYI-LABEL: @test_vaddv_f32(
18387-
// NYI: [[VADDV_F32_I:%.*]] = call float @llvm.aarch64.neon.faddv.f32.v2f32(<2 x float> %a)
18388-
// NYI: ret float [[VADDV_F32_I]]
18389-
// float32_t test_vaddv_f32(float32x2_t a) {
18390-
// return vaddv_f32(a);
18391-
// }
18386+
float32_t test_vaddv_f32(float32x2_t a) {
18387+
return vaddv_f32(a);
1839218388

18393-
// NYI-LABEL: @test_vaddvq_f32(
18394-
// NYI: [[VADDVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.faddv.f32.v4f32(<4 x float> %a)
18395-
// NYI: ret float [[VADDVQ_F32_I]]
18396-
// float32_t test_vaddvq_f32(float32x4_t a) {
18397-
// return vaddvq_f32(a);
18398-
// }
18389+
// CIR-LABEL: vaddv_f32
18390+
// CIR: cir.llvm.intrinsic "aarch64.neon.faddv" {{%.*}} : (!cir.vector<!cir.float x 2>) -> !cir.float
1839918391

18400-
// NYI-LABEL: @test_vaddvq_f64(
18401-
// NYI: [[VADDVQ_F64_I:%.*]] = call double @llvm.aarch64.neon.faddv.f64.v2f64(<2 x double> %a)
18402-
// NYI: ret double [[VADDVQ_F64_I]]
18403-
// float64_t test_vaddvq_f64(float64x2_t a) {
18404-
// return vaddvq_f64(a);
18405-
// }
18392+
// LLVM-LABEL: test_vaddv_f32
18393+
// LLVM-SAME: (<2 x float> [[a:%.*]])
18394+
// LLVM: [[VADDV_F32_I:%.*]] = call float @llvm.aarch64.neon.faddv.f32.v2f32(<2 x float> [[a]])
18395+
// LLVM: ret float [[VADDV_F32_I]]
18396+
}
18397+
18398+
float32_t test_vaddvq_f32(float32x4_t a) {
18399+
return vaddvq_f32(a);
18400+
18401+
// CIR-LABEL: vaddvq_f32
18402+
// CIR: cir.llvm.intrinsic "aarch64.neon.faddv" {{%.*}} : (!cir.vector<!cir.float x 4>) -> !cir.float
18403+
18404+
// LLVM-LABEL: test_vaddvq_f32
18405+
// LLVM-SAME: (<4 x float> [[a:%.*]])
18406+
// LLVM: [[VADDVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.faddv.f32.v4f32(<4 x float> [[a]])
18407+
// LLVM: ret float [[VADDVQ_F32_I]]
18408+
}
18409+
18410+
float64_t test_vaddvq_f64(float64x2_t a) {
18411+
return vaddvq_f64(a);
18412+
18413+
// CIR-LABEL: vaddvq_f64
18414+
// CIR: cir.llvm.intrinsic "aarch64.neon.faddv" {{%.*}} : (!cir.vector<!cir.double x 2>) -> !cir.double
18415+
18416+
// LLVM-LABEL: test_vaddvq_f64
18417+
// LLVM-SAME: (<2 x double> [[a:%.*]])
18418+
// LLVM: [[VADDVQ_F64_I:%.*]] = call double @llvm.aarch64.neon.faddv.f64.v2f64(<2 x double> [[a]])
18419+
// LLVM: ret double [[VADDVQ_F64_I]]
18420+
}
1840618421

1840718422
// NYI-LABEL: @test_vmaxv_f32(
1840818423
// NYI: [[VMAXV_F32_I:%.*]] = call float @llvm.aarch64.neon.fmaxv.f32.v2f32(<2 x float> %a)

0 commit comments

Comments
 (0)