Skip to content

Commit 9041625

Browse files
ghehglanza
authored andcommitted
[CIR][CIRGen][Builtin][Neon] Lower vld1_dup and vld1q_dup (#936)
1 parent 86f659d commit 9041625

File tree

2 files changed

+213
-1
lines changed

2 files changed

+213
-1
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3456,7 +3456,11 @@ CIRGenFunction::buildAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E,
34563456
}
34573457
case NEON::BI__builtin_neon_vld1_dup_v:
34583458
case NEON::BI__builtin_neon_vld1q_dup_v: {
3459-
llvm_unreachable("NYI");
3459+
cir::Address ptrAddr = PtrOp0.withElementType(vTy.getEltType());
3460+
mlir::Value val = builder.createLoad(getLoc(E->getExprLoc()), ptrAddr);
3461+
mlir::cir::VecSplatOp vecSplat = builder.create<mlir::cir::VecSplatOp>(
3462+
getLoc(E->getExprLoc()), vTy, val);
3463+
return vecSplat;
34603464
}
34613465
case NEON::BI__builtin_neon_vst1_lane_v:
34623466
case NEON::BI__builtin_neon_vst1q_lane_v: {

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

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17577,3 +17577,211 @@ int32x2_t test_vmovn_s64(int64x2_t a) {
1757717577
// LLVM: [[VMOVN_I:%.*]] = trunc <2 x i64> [[A]] to <2 x i32>
1757817578
// LLVM: ret <2 x i32> [[VMOVN_I]]
1757917579
}
17580+
17581+
uint8x8_t test_vld1_dup_u8(uint8_t const * ptr) {
17582+
return vld1_dup_u8(ptr);
17583+
}
17584+
17585+
// CIR-LABEL: vld1_dup_u8
17586+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!u8i>, !u8i
17587+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !u8i, !cir.vector<!u8i x 8>
17588+
17589+
// LLVM: {{.*}}test_vld1_dup_u8(ptr{{.*}}[[PTR:%.*]])
17590+
// LLVM: [[VAL:%.*]] = load i8, ptr [[PTR]], align 1
17591+
// LLVM: [[VEC:%.*]] = insertelement <8 x i8> poison, i8 [[VAL]], i64 0
17592+
// LLVM: {{%.*}} = shufflevector <8 x i8> [[VEC]], <8 x i8> poison, <8 x i32> zeroinitializer
17593+
17594+
int8x8_t test_vld1_dup_s8(int8_t const * ptr) {
17595+
return vld1_dup_s8(ptr);
17596+
}
17597+
17598+
// CIR-LABEL: test_vld1_dup_s8
17599+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!s8i>, !s8i
17600+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !s8i, !cir.vector<!s8i x 8>
17601+
17602+
// LLVM: {{.*}}test_vld1_dup_s8(ptr{{.*}}[[PTR:%.*]])
17603+
// LLVM: [[VAL:%.*]] = load i8, ptr [[PTR]], align 1
17604+
// LLVM: [[VEC:%.*]] = insertelement <8 x i8> poison, i8 [[VAL]], i64 0
17605+
// LLVM: {{%.*}} = shufflevector <8 x i8> [[VEC]], <8 x i8> poison, <8 x i32> zeroinitializer
17606+
17607+
uint16x4_t test_vld1_dup_u16(uint16_t const * ptr) {
17608+
return vld1_dup_u16(ptr);
17609+
}
17610+
17611+
// CIR-LABEL: test_vld1_dup_u16
17612+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!u16i>, !u16i
17613+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !u16i, !cir.vector<!u16i x 4>
17614+
17615+
// LLVM: {{.*}}test_vld1_dup_u16(ptr{{.*}}[[PTR:%.*]])
17616+
// LLVM: [[VAL:%.*]] = load i16, ptr [[PTR]], align 2
17617+
// LLVM: [[VEC:%.*]] = insertelement <4 x i16> poison, i16 [[VAL]], i64 0
17618+
// LLVM: {{%.*}} = shufflevector <4 x i16> [[VEC]], <4 x i16> poison, <4 x i32> zeroinitializer
17619+
17620+
int16x4_t test_vld1_dup_s16(int16_t const * ptr) {
17621+
return vld1_dup_s16(ptr);
17622+
}
17623+
17624+
// CIR-LABEL: test_vld1_dup_s16
17625+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!s16i>, !s16i
17626+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !s16i, !cir.vector<!s16i x 4>
17627+
17628+
// LLVM: {{.*}}test_vld1_dup_s16(ptr{{.*}}[[PTR:%.*]])
17629+
// LLVM: [[VAL:%.*]] = load i16, ptr [[PTR]], align 2
17630+
// LLVM: [[VEC:%.*]] = insertelement <4 x i16> poison, i16 [[VAL]], i64 0
17631+
// LLVM: {{%.*}} = shufflevector <4 x i16> [[VEC]], <4 x i16> poison, <4 x i32> zeroinitializer
17632+
17633+
int32x2_t test_vld1_dup_s32(int32_t const * ptr) {
17634+
return vld1_dup_s32(ptr);
17635+
}
17636+
17637+
// CIR-LABEL: test_vld1_dup_s32
17638+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!s32i>, !s32i
17639+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !s32i, !cir.vector<!s32i x 2>
17640+
17641+
// LLVM: {{.*}}test_vld1_dup_s32(ptr{{.*}}[[PTR:%.*]])
17642+
// LLVM: [[VAL:%.*]] = load i32, ptr [[PTR]], align 4
17643+
// LLVM: [[VEC:%.*]] = insertelement <2 x i32> poison, i32 [[VAL]], i64 0
17644+
// LLVM: {{%.*}} = shufflevector <2 x i32> [[VEC]], <2 x i32> poison, <2 x i32> zeroinitializer
17645+
17646+
int64x1_t test_vld1_dup_s64(int64_t const * ptr) {
17647+
return vld1_dup_s64(ptr);
17648+
}
17649+
17650+
// CIR-LABEL: test_vld1_dup_s64
17651+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!s64i>, !s64i
17652+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !s64i, !cir.vector<!s64i x 1>
17653+
17654+
// LLVM: {{.*}}test_vld1_dup_s64(ptr{{.*}}[[PTR:%.*]])
17655+
// LLVM: [[VAL:%.*]] = load i64, ptr [[PTR]], align 8
17656+
// LLVM: [[VEC:%.*]] = insertelement <1 x i64> poison, i64 [[VAL]], i64 0
17657+
// LLVM: {{%.*}} = shufflevector <1 x i64> [[VEC]], <1 x i64> poison, <1 x i32> zeroinitializer
17658+
17659+
float32x2_t test_vld1_dup_f32(float32_t const * ptr) {
17660+
return vld1_dup_f32(ptr);
17661+
}
17662+
17663+
// CIR-LABEL: test_vld1_dup_f32
17664+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!cir.float>, !cir.float
17665+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !cir.float, !cir.vector<!cir.float x 2>
17666+
17667+
// LLVM: {{.*}}test_vld1_dup_f32(ptr{{.*}}[[PTR:%.*]])
17668+
// LLVM: [[VAL:%.*]] = load float, ptr [[PTR]], align 4
17669+
// LLVM: [[VEC:%.*]] = insertelement <2 x float> poison, float [[VAL]], i64 0
17670+
// LLVM: {{%.*}} = shufflevector <2 x float> [[VEC]], <2 x float> poison, <2 x i32> zeroinitializer
17671+
17672+
float64x1_t test_vld1_dup_f64(float64_t const * ptr) {
17673+
return vld1_dup_f64(ptr);
17674+
}
17675+
17676+
// CIR-LABEL: test_vld1_dup_f64
17677+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!cir.double>, !cir.double
17678+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !cir.double, !cir.vector<!cir.double x 1>
17679+
17680+
// LLVM: {{.*}}test_vld1_dup_f64(ptr{{.*}}[[PTR:%.*]])
17681+
// LLVM: [[VAL:%.*]] = load double, ptr [[PTR]], align 8
17682+
// LLVM: [[VEC:%.*]] = insertelement <1 x double> poison, double [[VAL]], i64 0
17683+
// LLVM: {{%.*}} = shufflevector <1 x double> [[VEC]], <1 x double> poison, <1 x i32> zeroinitializer
17684+
17685+
uint8x16_t test_vld1q_dup_u8(uint8_t const * ptr) {
17686+
return vld1q_dup_u8(ptr);
17687+
}
17688+
17689+
// CIR-LABEL: test_vld1q_dup_u8
17690+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!u8i>, !u8i
17691+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !u8i, !cir.vector<!u8i x 16>
17692+
17693+
// LLVM: {{.*}}test_vld1q_dup_u8(ptr{{.*}}[[PTR:%.*]])
17694+
// LLVM: [[VAL:%.*]] = load i8, ptr [[PTR]], align 1
17695+
// LLVM: [[VEC:%.*]] = insertelement <16 x i8> poison, i8 [[VAL]], i64 0
17696+
// LLVM: {{%.*}} = shufflevector <16 x i8> [[VEC]], <16 x i8> poison, <16 x i32> zeroinitializer
17697+
17698+
int8x16_t test_vld1q_dup_s8(int8_t const * ptr) {
17699+
return vld1q_dup_s8(ptr);
17700+
}
17701+
17702+
// CIR-LABEL: test_vld1q_dup_s8
17703+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!s8i>, !s8i
17704+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !s8i, !cir.vector<!s8i x 16>
17705+
17706+
// LLVM: {{.*}}test_vld1q_dup_s8(ptr{{.*}}[[PTR:%.*]])
17707+
// LLVM: [[VAL:%.*]] = load i8, ptr [[PTR]], align 1
17708+
// LLVM: [[VEC:%.*]] = insertelement <16 x i8> poison, i8 [[VAL]], i64 0
17709+
// LLVM: {{%.*}} = shufflevector <16 x i8> [[VEC]], <16 x i8> poison, <16 x i32> zeroinitializer
17710+
17711+
uint16x8_t test_vld1q_dup_u16(uint16_t const * ptr) {
17712+
return vld1q_dup_u16(ptr);
17713+
}
17714+
17715+
// CIR-LABEL: test_vld1q_dup_u16
17716+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!u16i>, !u16i
17717+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !u16i, !cir.vector<!u16i x 8>
17718+
17719+
// LLVM: {{.*}}test_vld1q_dup_u16(ptr{{.*}}[[PTR:%.*]])
17720+
// LLVM: [[VAL:%.*]] = load i16, ptr [[PTR]], align 2
17721+
// LLVM: [[VEC:%.*]] = insertelement <8 x i16> poison, i16 [[VAL]], i64 0
17722+
// LLVM: {{%.*}} = shufflevector <8 x i16> [[VEC]], <8 x i16> poison, <8 x i32> zeroinitializer
17723+
17724+
int16x8_t test_vld1q_dup_s16(int16_t const * ptr) {
17725+
return vld1q_dup_s16(ptr);
17726+
}
17727+
17728+
// CIR-LABEL: test_vld1q_dup_s16
17729+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!s16i>, !s16i
17730+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !s16i, !cir.vector<!s16i x 8>
17731+
17732+
// LLVM: {{.*}}test_vld1q_dup_s16(ptr{{.*}}[[PTR:%.*]])
17733+
// LLVM: [[VAL:%.*]] = load i16, ptr [[PTR]], align 2
17734+
// LLVM: [[VEC:%.*]] = insertelement <8 x i16> poison, i16 [[VAL]], i64 0
17735+
// LLVM: {{%.*}} = shufflevector <8 x i16> [[VEC]], <8 x i16> poison, <8 x i32> zeroinitializer
17736+
17737+
int32x4_t test_vld1q_dup_s32(int32_t const * ptr) {
17738+
return vld1q_dup_s32(ptr);
17739+
}
17740+
17741+
// CIR-LABEL: test_vld1q_dup_s32
17742+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!s32i>, !s32i
17743+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !s32i, !cir.vector<!s32i x 4>
17744+
17745+
// LLVM: {{.*}}test_vld1q_dup_s32(ptr{{.*}}[[PTR:%.*]])
17746+
// LLVM: [[VAL:%.*]] = load i32, ptr [[PTR]], align 4
17747+
// LLVM: [[VEC:%.*]] = insertelement <4 x i32> poison, i32 [[VAL]], i64 0
17748+
// LLVM: {{%.*}} = shufflevector <4 x i32> [[VEC]], <4 x i32> poison, <4 x i32> zeroinitializer
17749+
17750+
int64x2_t test_vld1q_dup_s64(int64_t const * ptr) {
17751+
return vld1q_dup_s64(ptr);
17752+
}
17753+
17754+
// CIR-LABEL: test_vld1q_dup_s64
17755+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!s64i>, !s64i
17756+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !s64i, !cir.vector<!s64i x 2>
17757+
17758+
// LLVM: {{.*}}test_vld1q_dup_s64(ptr{{.*}}[[PTR:%.*]])
17759+
// LLVM: [[VAL:%.*]] = load i64, ptr [[PTR]], align 8
17760+
// LLVM: [[VEC:%.*]] = insertelement <2 x i64> poison, i64 [[VAL]], i64 0
17761+
// LLVM: {{%.*}} = shufflevector <2 x i64> [[VEC]], <2 x i64> poison, <2 x i32> zeroinitializer
17762+
17763+
float32x4_t test_vld1q_dup_f32(float32_t const * ptr) {
17764+
return vld1q_dup_f32(ptr);
17765+
}
17766+
17767+
// CIR-LABEL: test_vld1q_dup_f32
17768+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!cir.float>, !cir.float
17769+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !cir.float, !cir.vector<!cir.float x 4>
17770+
17771+
// LLVM: {{.*}}test_vld1q_dup_f32(ptr{{.*}}[[PTR:%.*]])
17772+
// LLVM: [[VAL:%.*]] = load float, ptr [[PTR]], align 4
17773+
// LLVM: [[VEC:%.*]] = insertelement <4 x float> poison, float [[VAL]], i64 0
17774+
// LLVM: {{%.*}} = shufflevector <4 x float> [[VEC]], <4 x float> poison, <4 x i32> zeroinitializer
17775+
17776+
float64x2_t test_vld1q_dup_f64(float64_t const * ptr) {
17777+
return vld1q_dup_f64(ptr);
17778+
}
17779+
17780+
// CIR-LABEL: test_vld1q_dup_f64
17781+
// CIR: [[VAL:%.*]] = cir.load {{%.*}} : !cir.ptr<!cir.double>, !cir.double
17782+
// CIR: {{%.*}} = cir.vec.splat [[VAL]] : !cir.double, !cir.vector<!cir.double x 2>
17783+
17784+
// LLVM: {{.*}}test_vld1q_dup_f64(ptr{{.*}}[[PTR:%.*]])
17785+
// LLVM: [[VAL:%.*]] = load double, ptr [[PTR]], align 8
17786+
// LLVM: [[VEC:%.*]] = insertelement <2 x double> poison, double [[VAL]], i64 0
17787+
// LLVM: {{%.*}} = shufflevector <2 x double> [[VEC]], <2 x double> poison, <2 x i32> zeroinitializer

0 commit comments

Comments
 (0)