https://github.com/banach-space created 
https://github.com/llvm/llvm-project/pull/217263

This PR adds lowering for intrinsic from the following groups:
* https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#conversions

It continues the work started in #190961, #193273, #199990, #209252,
, #211609,  #216757 and #217017.

This PR implements the conversions for the following:
1) "int to float" intrinsics:
   * vcvt_f32_s32
   * vcvtq_f32_s32
   * vcvt_f32_u32
   * vcvtq_f32_u32
   * vcvts_f32_s32
   * vcvts_f32_u32
   * vcvt_f64_s64
   * vcvtq_f64_s64
   * vcvt_f64_u64
   * vcvtq_f64_u64
   * vcvtd_f64_s64
   * vcvtd_f64_u64

2) "float width conversion" intrnsics:
   * vcvt_f16_f32
   * vcvt_high_f16_f32
   * vcvt_f32_f64
   * vcvt_high_f32_f64
   * vcvt_f32_f16
   * vcvt_high_f32_f16
   * vcvt_f64_f32
   * vcvt_high_f64_f32
   * vcvtx_f32_f64
   * vcvtxd_f32_f64
   * vcvtx_high_f32_f64

The corresponding tests are moved from:
  * clang/test/CodeGen/AArch64/

to:
  * clang/test/CodeGen/AArch64/neon/

The lowering follows the existing implementation in
CodeGen/TargetBuiltins/ARM.cpp.


From 37f338eebbeaf2bd685164dc508131d95a95a98c Mon Sep 17 00:00:00 2001
From: Andrzej Warzynski <[email protected]>
Date: Wed, 19 Aug 2026 10:04:55 +0000
Subject: [PATCH] [clang][CIR][AArch64] Add lowering for conversion intrinsics

This PR adds lowering for intrinsic from the following groups:
* https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#conversions

It continues the work started in #190961, #193273, #199990, #209252,
, #211609,  #216757 and #217017.

This PR implements the conversions for the following:
1) "int to float" intrinsics:
   * vcvt_f32_s32
   * vcvtq_f32_s32
   * vcvt_f32_u32
   * vcvtq_f32_u32
   * vcvts_f32_s32
   * vcvts_f32_u32
   * vcvt_f64_s64
   * vcvtq_f64_s64
   * vcvt_f64_u64
   * vcvtq_f64_u64
   * vcvtd_f64_s64
   * vcvtd_f64_u64

2) "float width conversion" intrnsics:
   * vcvt_f16_f32
   * vcvt_high_f16_f32
   * vcvt_f32_f64
   * vcvt_high_f32_f64
   * vcvt_f32_f16
   * vcvt_high_f32_f16
   * vcvt_f64_f32
   * vcvt_high_f64_f32
   * vcvtx_f32_f64
   * vcvtxd_f32_f64
   * vcvtx_high_f32_f64

The corresponding tests are moved from:
  * clang/test/CodeGen/AArch64/

to:
  * clang/test/CodeGen/AArch64/neon/

The lowering follows the existing implementation in
CodeGen/TargetBuiltins/ARM.cpp.
---
 .../lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp  |  64 +++-
 .../CodeGen/AArch64/neon-fcvt-intrinsics.c    |  17 -
 clang/test/CodeGen/AArch64/neon-intrinsics.c  |  64 ----
 clang/test/CodeGen/AArch64/neon-misc.c        | 194 -----------
 clang/test/CodeGen/AArch64/neon/intrinsics.c  | 317 ++++++++++++++++++
 5 files changed, 374 insertions(+), 282 deletions(-)
 delete mode 100644 clang/test/CodeGen/AArch64/neon-fcvt-intrinsics.c

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
index f2bc4141f433e..47237d57b2760 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
@@ -483,6 +483,7 @@ emitCommonNeonSISDBuiltinExpr(CIRGenFunction &cgf,
   case NEON::BI__builtin_neon_vcvtad_u32_f64:
   case NEON::BI__builtin_neon_vcvtad_s64_f64:
   case NEON::BI__builtin_neon_vcvtad_u64_f64:
+  case NEON::BI__builtin_neon_vcvtxd_f32_f64:
   case NEON::BI__builtin_neon_vaddlv_s32:
   case NEON::BI__builtin_neon_vaddlv_u32:
   case NEON::BI__builtin_neon_vaddlvq_s32:
@@ -789,6 +790,7 @@ static mlir::Value emitCommonNeonBuiltinExpr(
   const bool isUnsigned = neonType.isUnsigned();
   const bool hasLegalHalfType = cgf.getTarget().hasFastHalfType();
   const bool usgn = neonType.isUnsigned();
+  const bool isQuad = neonType.isQuad();
 
   // The value of allowBFloatArgsAndRet is true for AArch64, but it should
   // come from ABI info.
@@ -908,8 +910,17 @@ static mlir::Value emitCommonNeonBuiltinExpr(
   case NEON::BI__builtin_neon_vcltzq_v:
   case NEON::BI__builtin_neon_vclz_v:
   case NEON::BI__builtin_neon_vclzq_v:
+    cgf.cgm.errorNYI(expr->getSourceRange(),
+                     std::string("unimplemented AArch64 builtin call: ") +
+                         ctx.BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
   case NEON::BI__builtin_neon_vcvt_f32_v:
-  case NEON::BI__builtin_neon_vcvtq_f32_v:
+  case NEON::BI__builtin_neon_vcvtq_f32_v: {
+    ops[0] = cgf.getBuilder().createBitcast(ops[0], ty);
+    ty = getNeonType(&cgf, NeonTypeFlags(NeonTypeFlags::Float32, false, 
isQuad),
+                     hasLegalHalfType);
+    return cgf.getBuilder().createCast(cir::CastKind::int_to_float, ops[0], 
ty);
+  }
   case NEON::BI__builtin_neon_vcvt_f16_s16:
   case NEON::BI__builtin_neon_vcvt_f16_u16:
   case NEON::BI__builtin_neon_vcvtq_f16_s16:
@@ -1030,7 +1041,19 @@ static mlir::Value emitCommonNeonBuiltinExpr(
   case NEON::BI__builtin_neon_vcvtmq_u16_f16:
   case NEON::BI__builtin_neon_vcvtmq_u32_v:
   case NEON::BI__builtin_neon_vcvtmq_u64_v:
-  case NEON::BI__builtin_neon_vcvtx_f32_v:
+    cgf.cgm.errorNYI(expr->getSourceRange(),
+                     std::string("unimplemented AArch64 builtin call: ") +
+                         ctx.BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
+  case NEON::BI__builtin_neon_vcvtx_f32_v: {
+    llvm::StringRef llvmIntrName = getLLVMIntrNameNoPrefix(
+        static_cast<llvm::Intrinsic::ID>(llvmIntrinsic));
+    auto v2f64 = cir::VectorType::get(cgf.cgm.doubleTy, 2);
+    auto v2f32 = cir::VectorType::get(cgf.cgm.floatTy, 2);
+    return emitNeonCall(cgf.getCIRGenModule(), cgf.getBuilder(),
+                        /*argTypes=*/{v2f64}, ops, llvmIntrName,
+                        /*funcResTy=*/v2f32, loc);
+  }
   case NEON::BI__builtin_neon_vext_v:
   case NEON::BI__builtin_neon_vextq_v:
     cgf.cgm.errorNYI(expr->getSourceRange(),
@@ -2628,7 +2651,10 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
   case NEON::BI__builtin_neon_vcvts_f32_u32:
   case NEON::BI__builtin_neon_vcvtd_f64_u64:
   case NEON::BI__builtin_neon_vcvts_f32_s32:
-  case NEON::BI__builtin_neon_vcvtd_f64_s64:
+  case NEON::BI__builtin_neon_vcvtd_f64_s64: {
+    return builder.createCast(loc, cir::CastKind::int_to_float, ops[0],
+                              convertType(expr->getType()));
+  }
   case NEON::BI__builtin_neon_vcvth_f16_u16:
   case NEON::BI__builtin_neon_vcvth_f16_u32:
   case NEON::BI__builtin_neon_vcvth_f16_u64:
@@ -2934,8 +2960,22 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
   case NEON::BI__builtin_neon_vcvt_bf16_f32:
   case NEON::BI__builtin_neon_vcvtq_low_bf16_f32:
   case NEON::BI__builtin_neon_vcvtq_high_bf16_f32:
-  case NEON::BI__builtin_neon_vcvt_f16_f32:
-  case NEON::BI__builtin_neon_vcvt_f32_f16:
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented AArch64 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
+  case NEON::BI__builtin_neon_vcvt_f16_f32: {
+    auto v4f32 = cir::VectorType::get(cgm.floatTy, 4);
+    auto v4f16 = cir::VectorType::get(cgm.fP16Ty, 4);
+    return builder.createFloatingCast(builder.createBitcast(ops[0], v4f32),
+                                      v4f16);
+  }
+  case NEON::BI__builtin_neon_vcvt_f32_f16: {
+    auto v4f32 = cir::VectorType::get(cgm.floatTy, 4);
+    auto v4f16 = cir::VectorType::get(cgm.fP16Ty, 4);
+    return builder.createFloatingCast(builder.createBitcast(ops[0], v4f16),
+                                      v4f32);
+  }
   case clang::AArch64::BI_InterlockedAdd:
   case clang::AArch64::BI_InterlockedAdd_acq:
   case clang::AArch64::BI_InterlockedAdd_rel:
@@ -3259,8 +3299,18 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     ty = getNeonType(
         this, NeonTypeFlags(NeonTypeFlags::Float64, false, type.isQuad()));
     return builder.createCast(loc, cir::CastKind::int_to_float, ops[0], ty);
-  case NEON::BI__builtin_neon_vcvt_f64_f32:
-  case NEON::BI__builtin_neon_vcvt_f32_f64:
+  case NEON::BI__builtin_neon_vcvt_f64_f32: {
+    auto v2f32 = cir::VectorType::get(cgm.floatTy, 2);
+    auto v2f64 = cir::VectorType::get(cgm.doubleTy, 2);
+    return builder.createFloatingCast(builder.createBitcast(ops[0], v2f32),
+                                      v2f64);
+  }
+  case NEON::BI__builtin_neon_vcvt_f32_f64: {
+    auto v2f32 = cir::VectorType::get(cgm.floatTy, 2);
+    auto v2f64 = cir::VectorType::get(cgm.doubleTy, 2);
+    return builder.createFloatingCast(builder.createBitcast(ops[0], v2f64),
+                                      v2f32);
+  }
   case NEON::BI__builtin_neon_vcvt_s32_v:
   case NEON::BI__builtin_neon_vcvt_u32_v:
   case NEON::BI__builtin_neon_vcvt_s64_v:
diff --git a/clang/test/CodeGen/AArch64/neon-fcvt-intrinsics.c 
b/clang/test/CodeGen/AArch64/neon-fcvt-intrinsics.c
deleted file mode 100644
index f460065112444..0000000000000
--- a/clang/test/CodeGen/AArch64/neon-fcvt-intrinsics.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --function-signature
-// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
-// RUN:  -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | 
FileCheck %s
-
-// REQUIRES: aarch64-registered-target || arm-registered-target
-
-#include <arm_neon.h>
-
-// CHECK-LABEL: define {{[^@]+}}@test_vcvtxd_f32_f64
-// CHECK-SAME: (double noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] {
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[VCVTXD_F32_F64_I:%.*]] = call float 
@llvm.aarch64.sisd.fcvtxn(double [[A]])
-// CHECK-NEXT:    ret float [[VCVTXD_F32_F64_I]]
-//
-float32_t test_vcvtxd_f32_f64(float64_t a) {
-  return (float32_t)vcvtxd_f32_f64(a);
-}
diff --git a/clang/test/CodeGen/AArch64/neon-intrinsics.c 
b/clang/test/CodeGen/AArch64/neon-intrinsics.c
index 79cb1c42cd5af..8515754922834 100644
--- a/clang/test/CodeGen/AArch64/neon-intrinsics.c
+++ b/clang/test/CodeGen/AArch64/neon-intrinsics.c
@@ -5264,46 +5264,6 @@ float64_t test_vrsqrtsd_f64(float64_t a, float64_t b) {
   return vrsqrtsd_f64(a, b);
 }
 
-// CHECK-LABEL: define dso_local float @test_vcvts_f32_s32(
-// CHECK-SAME: i32 noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = sitofp i32 [[A]] to float
-// CHECK-NEXT:    ret float [[TMP0]]
-//
-float32_t test_vcvts_f32_s32(int32_t a) {
-  return vcvts_f32_s32(a);
-}
-
-// CHECK-LABEL: define dso_local double @test_vcvtd_f64_s64(
-// CHECK-SAME: i64 noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = sitofp i64 [[A]] to double
-// CHECK-NEXT:    ret double [[TMP0]]
-//
-float64_t test_vcvtd_f64_s64(int64_t a) {
-  return vcvtd_f64_s64(a);
-}
-
-// CHECK-LABEL: define dso_local float @test_vcvts_f32_u32(
-// CHECK-SAME: i32 noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = uitofp i32 [[A]] to float
-// CHECK-NEXT:    ret float [[TMP0]]
-//
-float32_t test_vcvts_f32_u32(uint32_t a) {
-  return vcvts_f32_u32(a);
-}
-
-// CHECK-LABEL: define dso_local double @test_vcvtd_f64_u64(
-// CHECK-SAME: i64 noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = uitofp i64 [[A]] to double
-// CHECK-NEXT:    ret double [[TMP0]]
-//
-float64_t test_vcvtd_f64_u64(uint64_t a) {
-  return vcvtd_f64_u64(a);
-}
-
 // CHECK-LABEL: define dso_local float @test_vrecpes_f32(
 // CHECK-SAME: float noundef [[A:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
@@ -12440,30 +12400,6 @@ float64x1_t test_vneg_f64(float64x1_t a) {
   return vneg_f64(a);
 }
 
-// CHECK-LABEL: define dso_local <1 x double> @test_vcvt_f64_s64(
-// CHECK-SAME: <1 x i64> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
-// CHECK-NEXT:    [[VCVT_I:%.*]] = sitofp <1 x i64> [[TMP1]] to <1 x double>
-// CHECK-NEXT:    ret <1 x double> [[VCVT_I]]
-//
-float64x1_t test_vcvt_f64_s64(int64x1_t a) {
-  return vcvt_f64_s64(a);
-}
-
-// CHECK-LABEL: define dso_local <1 x double> @test_vcvt_f64_u64(
-// CHECK-SAME: <1 x i64> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
-// CHECK-NEXT:    [[VCVT_I:%.*]] = uitofp <1 x i64> [[TMP1]] to <1 x double>
-// CHECK-NEXT:    ret <1 x double> [[VCVT_I]]
-//
-float64x1_t test_vcvt_f64_u64(uint64x1_t a) {
-  return vcvt_f64_u64(a);
-}
-
 // CHECK-LABEL: define dso_local <1 x double> @test_vrsqrte_f64(
 // CHECK-SAME: <1 x double> noundef [[A:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
diff --git a/clang/test/CodeGen/AArch64/neon-misc.c 
b/clang/test/CodeGen/AArch64/neon-misc.c
index cfc85c7bd3c52..253c4eb7a1316 100644
--- a/clang/test/CodeGen/AArch64/neon-misc.c
+++ b/clang/test/CodeGen/AArch64/neon-misc.c
@@ -2614,128 +2614,6 @@ float16x4_t test_vcvt_f16_f32(float32x4_t a) {
   return vcvt_f16_f32(a);
 }
 
-// CHECK-LABEL: define dso_local <8 x half> @test_vcvt_high_f16_f32(
-// CHECK-SAME: <4 x half> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) 
#[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x float> [[B]] to <4 x i32>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
-// CHECK-NEXT:    [[TMP3:%.*]] = fptrunc <4 x float> [[TMP2]] to <4 x half>
-// CHECK-NEXT:    [[SHUFFLE_I:%.*]] = shufflevector <4 x half> [[A]], <4 x 
half> [[TMP3]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 
7>
-// CHECK-NEXT:    ret <8 x half> [[SHUFFLE_I]]
-//
-float16x8_t test_vcvt_high_f16_f32(float16x4_t a, float32x4_t b) {
-  return vcvt_high_f16_f32(a, b);
-}
-
-// CHECK-LABEL: define dso_local <2 x float> @test_vcvt_f32_f64(
-// CHECK-SAME: <2 x double> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x double>
-// CHECK-NEXT:    [[VCVT_I:%.*]] = fptrunc <2 x double> [[TMP2]] to <2 x float>
-// CHECK-NEXT:    ret <2 x float> [[VCVT_I]]
-//
-float32x2_t test_vcvt_f32_f64(float64x2_t a) {
-  return vcvt_f32_f64(a);
-}
-
-// CHECK-LABEL: define dso_local <4 x float> @test_vcvt_high_f32_f64(
-// CHECK-SAME: <2 x float> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) 
#[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x double> [[B]] to <2 x i64>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x double>
-// CHECK-NEXT:    [[VCVT_I_I:%.*]] = fptrunc <2 x double> [[TMP2]] to <2 x 
float>
-// CHECK-NEXT:    [[SHUFFLE_I:%.*]] = shufflevector <2 x float> [[A]], <2 x 
float> [[VCVT_I_I]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
-// CHECK-NEXT:    ret <4 x float> [[SHUFFLE_I]]
-//
-float32x4_t test_vcvt_high_f32_f64(float32x2_t a, float64x2_t b) {
-  return vcvt_high_f32_f64(a, b);
-}
-
-// CHECK-LABEL: define dso_local <2 x float> @test_vcvtx_f32_f64(
-// CHECK-SAME: <2 x double> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
-// CHECK-NEXT:    [[VCVTX_F32_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x 
double>
-// CHECK-NEXT:    [[VCVTX_F32_V1_I:%.*]] = call <2 x float> 
@llvm.aarch64.neon.fcvtxn.v2f32.v2f64(<2 x double> [[VCVTX_F32_V_I]])
-// CHECK-NEXT:    ret <2 x float> [[VCVTX_F32_V1_I]]
-//
-float32x2_t test_vcvtx_f32_f64(float64x2_t a) {
-  return vcvtx_f32_f64(a);
-}
-
-// CHECK-LABEL: define dso_local <4 x float> @test_vcvtx_high_f32_f64(
-// CHECK-SAME: <2 x float> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) 
#[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x double> [[B]] to <2 x i64>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
-// CHECK-NEXT:    [[VCVTX_F32_V_I_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x 
double>
-// CHECK-NEXT:    [[VCVTX_F32_V1_I_I:%.*]] = call <2 x float> 
@llvm.aarch64.neon.fcvtxn.v2f32.v2f64(<2 x double> [[VCVTX_F32_V_I_I]])
-// CHECK-NEXT:    [[SHUFFLE_I:%.*]] = shufflevector <2 x float> [[A]], <2 x 
float> [[VCVTX_F32_V1_I_I]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
-// CHECK-NEXT:    ret <4 x float> [[SHUFFLE_I]]
-//
-float32x4_t test_vcvtx_high_f32_f64(float32x2_t a, float64x2_t b) {
-  return vcvtx_high_f32_f64(a, b);
-}
-
-// CHECK-LABEL: define dso_local <4 x float> @test_vcvt_f32_f16(
-// CHECK-SAME: <4 x half> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <4 x i16>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i16> [[TMP0]] to <8 x i8>
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half>
-// CHECK-NEXT:    [[TMP3:%.*]] = fpext <4 x half> [[TMP2]] to <4 x float>
-// CHECK-NEXT:    ret <4 x float> [[TMP3]]
-//
-float32x4_t test_vcvt_f32_f16(float16x4_t a) {
-  return vcvt_f32_f16(a);
-}
-
-// CHECK-LABEL: define dso_local <4 x float> @test_vcvt_high_f32_f16(
-// CHECK-SAME: <8 x half> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x 
half> [[A]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x half> [[SHUFFLE_I]] to <4 x i16>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i16> [[TMP0]] to <8 x i8>
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half>
-// CHECK-NEXT:    [[TMP3:%.*]] = fpext <4 x half> [[TMP2]] to <4 x float>
-// CHECK-NEXT:    ret <4 x float> [[TMP3]]
-//
-float32x4_t test_vcvt_high_f32_f16(float16x8_t a) {
-  return vcvt_high_f32_f16(a);
-}
-
-// CHECK-LABEL: define dso_local <2 x double> @test_vcvt_f64_f32(
-// CHECK-SAME: <2 x float> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
-// CHECK-NEXT:    [[VCVT_I:%.*]] = fpext <2 x float> [[TMP2]] to <2 x double>
-// CHECK-NEXT:    ret <2 x double> [[VCVT_I]]
-//
-float64x2_t test_vcvt_f64_f32(float32x2_t a) {
-  return vcvt_f64_f32(a);
-}
-
-// CHECK-LABEL: define dso_local <2 x double> @test_vcvt_high_f64_f32(
-// CHECK-SAME: <4 x float> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[SHUFFLE_I:%.*]] = shufflevector <4 x float> [[A]], <4 x 
float> [[A]], <2 x i32> <i32 2, i32 3>
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x float> [[SHUFFLE_I]] to <2 x i32>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
-// CHECK-NEXT:    [[VCVT_I_I:%.*]] = fpext <2 x float> [[TMP2]] to <2 x double>
-// CHECK-NEXT:    ret <2 x double> [[VCVT_I_I]]
-//
-float64x2_t test_vcvt_high_f64_f32(float32x4_t a) {
-  return vcvt_high_f64_f32(a);
-}
-
 // CHECK-LABEL: define dso_local <2 x double> @test_vrndnq_f64(
 // CHECK-SAME: <2 x double> noundef [[A:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
@@ -2928,75 +2806,3 @@ uint32x2_t test_vrecpe_u32(uint32x2_t a) {
 uint32x4_t test_vrecpeq_u32(uint32x4_t a) {
   return vrecpeq_u32(a);
 }
-
-// CHECK-LABEL: define dso_local <2 x float> @test_vcvt_f32_s32(
-// CHECK-SAME: <2 x i32> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
-// CHECK-NEXT:    [[VCVT_I:%.*]] = sitofp <2 x i32> [[TMP1]] to <2 x float>
-// CHECK-NEXT:    ret <2 x float> [[VCVT_I]]
-//
-float32x2_t test_vcvt_f32_s32(int32x2_t a) {
-  return vcvt_f32_s32(a);
-}
-
-// CHECK-LABEL: define dso_local <2 x float> @test_vcvt_f32_u32(
-// CHECK-SAME: <2 x i32> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
-// CHECK-NEXT:    [[VCVT_I:%.*]] = uitofp <2 x i32> [[TMP1]] to <2 x float>
-// CHECK-NEXT:    ret <2 x float> [[VCVT_I]]
-//
-float32x2_t test_vcvt_f32_u32(uint32x2_t a) {
-  return vcvt_f32_u32(a);
-}
-
-// CHECK-LABEL: define dso_local <4 x float> @test_vcvtq_f32_s32(
-// CHECK-SAME: <4 x i32> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
-// CHECK-NEXT:    [[VCVT_I:%.*]] = sitofp <4 x i32> [[TMP1]] to <4 x float>
-// CHECK-NEXT:    ret <4 x float> [[VCVT_I]]
-//
-float32x4_t test_vcvtq_f32_s32(int32x4_t a) {
-  return vcvtq_f32_s32(a);
-}
-
-// CHECK-LABEL: define dso_local <4 x float> @test_vcvtq_f32_u32(
-// CHECK-SAME: <4 x i32> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
-// CHECK-NEXT:    [[VCVT_I:%.*]] = uitofp <4 x i32> [[TMP1]] to <4 x float>
-// CHECK-NEXT:    ret <4 x float> [[VCVT_I]]
-//
-float32x4_t test_vcvtq_f32_u32(uint32x4_t a) {
-  return vcvtq_f32_u32(a);
-}
-
-// CHECK-LABEL: define dso_local <2 x double> @test_vcvtq_f64_s64(
-// CHECK-SAME: <2 x i64> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
-// CHECK-NEXT:    [[VCVT_I:%.*]] = sitofp <2 x i64> [[TMP1]] to <2 x double>
-// CHECK-NEXT:    ret <2 x double> [[VCVT_I]]
-//
-float64x2_t test_vcvtq_f64_s64(int64x2_t a) {
-  return vcvtq_f64_s64(a);
-}
-
-// CHECK-LABEL: define dso_local <2 x double> @test_vcvtq_f64_u64(
-// CHECK-SAME: <2 x i64> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
-// CHECK-NEXT:    [[VCVT_I:%.*]] = uitofp <2 x i64> [[TMP1]] to <2 x double>
-// CHECK-NEXT:    ret <2 x double> [[VCVT_I]]
-//
-float64x2_t test_vcvtq_f64_u64(uint64x2_t a) {
-  return vcvtq_f64_u64(a);
-}
diff --git a/clang/test/CodeGen/AArch64/neon/intrinsics.c 
b/clang/test/CodeGen/AArch64/neon/intrinsics.c
index 12b181a4ee917..ece2da21557c7 100644
--- a/clang/test/CodeGen/AArch64/neon/intrinsics.c
+++ b/clang/test/CodeGen/AArch64/neon/intrinsics.c
@@ -5452,6 +5452,323 @@ uint32_t test_vcvtad_u32_f64(float64_t a) {
   return (uint32_t)vcvtad_u32_f64(a);
 }
 
+//===------------------------------------------------------===//
+// 2.1.4.1 Convearions (int to float)
+// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#conversions
+//===------------------------------------------------------===//
+// LLVM-LABEL: @test_vcvt_f32_s32(
+// CIR-LABEL: @vcvt_f32_s32(
+float32x2_t test_vcvt_f32_s32(int32x2_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]])
+// LLVM:    [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
+// LLVM:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
+// LLVM:    [[VCVT_I:%.*]] = sitofp <2 x i32> [[TMP1]] to <2 x float>
+// LLVM:    ret <2 x float> [[VCVT_I]]
+  return vcvt_f32_s32(a);
+}
+
+// LLVM-LABEL: @test_vcvtq_f32_s32(
+// CIR-LABEL: @vcvtq_f32_s32(
+float32x4_t test_vcvtq_f32_s32(int32x4_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
+// LLVM:    [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
+// LLVM:    [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
+// LLVM:    [[VCVT_I:%.*]] = sitofp <4 x i32> [[TMP1]] to <4 x float>
+// LLVM:    ret <4 x float> [[VCVT_I]]
+  return vcvtq_f32_s32(a);
+}
+
+// LLVM-LABEL: @test_vcvt_f32_u32(
+// CIR-LABEL: @vcvt_f32_u32(
+float32x2_t test_vcvt_f32_u32(uint32x2_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]]) #[[ATTR0]] {
+// LLVM:    [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
+// LLVM:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
+// LLVM:    [[VCVT_I:%.*]] = uitofp <2 x i32> [[TMP1]] to <2 x float>
+// LLVM:    ret <2 x float> [[VCVT_I]]
+  return vcvt_f32_u32(a);
+}
+
+// LLVM-LABEL: @test_vcvtq_f32_u32(
+// CIR-LABEL: @vcvtq_f32_u32(
+float32x4_t test_vcvtq_f32_u32(uint32x4_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]]) #[[ATTR0]] {
+// LLVM:    [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
+// LLVM:    [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
+// LLVM:    [[VCVT_I:%.*]] = uitofp <4 x i32> [[TMP1]] to <4 x float>
+// LLVM:    ret <4 x float> [[VCVT_I]]
+  return vcvtq_f32_u32(a);
+}
+
+// LLVM-LABEL: @test_vcvts_f32_s32(
+// CIR-LABEL: @vcvts_f32_s32(
+float32_t test_vcvts_f32_s32(int32_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: i32 {{.*}} [[A:%.*]])
+// LLVM:    [[TMP0:%.*]] = sitofp i32 [[A]] to float
+// LLVM:    ret float [[TMP0]]
+  return vcvts_f32_s32(a);
+}
+
+// LLVM-LABEL: @test_vcvts_f32_u32(
+// CIR-LABEL: @vcvts_f32_u32(
+float32_t test_vcvts_f32_u32(uint32_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: i32 {{.*}} [[A:%.*]]) #[[ATTR0]] {
+// LLVM:    [[TMP0:%.*]] = uitofp i32 [[A]] to float
+// LLVM:    ret float [[TMP0]]
+  return vcvts_f32_u32(a);
+}
+
+// LLVM-LABEL: @test_vcvt_f64_s64(
+// CIR-LABEL: @vcvt_f64_s64(
+float64x1_t test_vcvt_f64_s64(int64x1_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
+// LLVM:    [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
+// LLVM:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
+// LLVM:    [[VCVT_I:%.*]] = sitofp <1 x i64> [[TMP1]] to <1 x double>
+// LLVM:    ret <1 x double> [[VCVT_I]]
+  return vcvt_f64_s64(a);
+}
+
+// LLVM-LABEL: @test_vcvtq_f64_s64(
+// CIR-LABEL: @vcvtq_f64_s64(
+float64x2_t test_vcvtq_f64_s64(int64x2_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
+// LLVM:    [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
+// LLVM:    [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
+// LLVM:    [[VCVT_I:%.*]] = sitofp <2 x i64> [[TMP1]] to <2 x double>
+// LLVM:    ret <2 x double> [[VCVT_I]]
+  return vcvtq_f64_s64(a);
+}
+
+// LLVM-LABEL: @test_vcvt_f64_u64(
+// CIR-LABEL: @vcvt_f64_u64(
+float64x1_t test_vcvt_f64_u64(uint64x1_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
+// LLVM:    [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
+// LLVM:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
+// LLVM:    [[VCVT_I:%.*]] = uitofp <1 x i64> [[TMP1]] to <1 x double>
+// LLVM:    ret <1 x double> [[VCVT_I]]
+  return vcvt_f64_u64(a);
+}
+
+// LLVM-LABEL: @test_vcvtq_f64_u64(
+// CIR-LABEL: @vcvtq_f64_u64(
+float64x2_t test_vcvtq_f64_u64(uint64x2_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
+// LLVM:    [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
+// LLVM:    [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
+// LLVM:    [[VCVT_I:%.*]] = uitofp <2 x i64> [[TMP1]] to <2 x double>
+// LLVM:    ret <2 x double> [[VCVT_I]]
+  return vcvtq_f64_u64(a);
+}
+
+// LLVM-LABEL: @test_vcvtd_f64_s64(
+// CIR-LABEL: @vcvtd_f64_s64(
+float64_t test_vcvtd_f64_s64(int64_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: i64 {{.*}} [[A:%.*]])
+// LLVM:    [[TMP0:%.*]] = sitofp i64 [[A]] to double
+// LLVM:    ret double [[TMP0]]
+  return vcvtd_f64_s64(a);
+}
+
+// LLVM-LABEL: @test_vcvtd_f64_u64(
+// CIR-LABEL: @vcvtd_f64_u64(
+float64_t test_vcvtd_f64_u64(uint64_t a) {
+// CIR:  cir.cast int_to_float
+
+// LLVM-SAME: i64 {{.*}} [[A:%.*]]) #[[ATTR0]] {
+// LLVM:    [[TMP0:%.*]] = uitofp i64 [[A]] to double
+// LLVM:    ret double [[TMP0]]
+  return vcvtd_f64_u64(a);
+}
+
+//===------------------------------------------------------===//
+// 2.1.4.1 Convearions (float width conversion)
+// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#conversions
+//===------------------------------------------------------===//
+// LLVM-LABEL: @test_vcvt_f16_f32(
+// CIR-LABEL: @vcvt_f16_f32(
+float16x4_t test_vcvt_f16_f32(float32x4_t a) {
+// CIR:  cir.cast floating
+
+// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]]) #[[ATTR0]] {
+// LLVM:    [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
+// LLVM:    [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
+// LLVM:    [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
+// LLVM:    [[TMP3:%.*]] = fptrunc <4 x float> [[TMP2]] to <4 x half>
+// LLVM:    ret <4 x half> [[TMP3]]
+  return vcvt_f16_f32(a);
+}
+
+// LLVM-LABEL: @test_vcvt_high_f16_f32(
+// CIR-LABEL: @vcvt_f16_f32(
+float16x8_t test_vcvt_high_f16_f32(float16x4_t a, float32x4_t b) {
+// CIR:  cir.call @vcvt_f16_f32
+// CIR: cir.call @vcombine_f16
+
+// LLVM-SAME: <4 x half> {{.*}} [[A:%.*]], <4 x float> {{.*}} [[B:%.*]]) 
#[[ATTR0]] {
+// LLVM:    [[TMP0:%.*]] = bitcast <4 x float> [[B]] to <4 x i32>
+// LLVM:    [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
+// LLVM:    [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
+// LLVM:    [[TMP3:%.*]] = fptrunc <4 x float> [[TMP2]] to <4 x half>
+// LLVM:    [[SHUFFLE_I:%.*]] = shufflevector <4 x half> [[A]], <4 x half> 
[[TMP3]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+// LLVM:    ret <8 x half> [[SHUFFLE_I]]
+  return vcvt_high_f16_f32(a, b);
+}
+
+// LLVM-LABEL: @test_vcvt_f32_f64(
+// CIR-LABEL: @vcvt_f32_f64(
+float32x2_t test_vcvt_f32_f64(float64x2_t a) {
+// CIR:  cir.cast floating
+
+// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]]) #[[ATTR0]] {
+// LLVM:    [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
+// LLVM:    [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
+// LLVM:    [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x double>
+// LLVM:    [[VCVT_I:%.*]] = fptrunc <2 x double> [[TMP2]] to <2 x float>
+// LLVM:    ret <2 x float> [[VCVT_I]]
+  return vcvt_f32_f64(a);
+}
+
+// LLVM-LABEL: @test_vcvt_high_f32_f64(
+// CIR-LABEL: @vcvt_high_f32_f64(
+float32x4_t test_vcvt_high_f32_f64(float32x2_t a, float64x2_t b) {
+// CIR:  cir.call @vcvt_f32_f64
+// CIR: cir.call @vcombine_f32
+
+// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]], <2 x double> {{.*}} [[B:%.*]])
+// LLVM:    [[TMP0:%.*]] = bitcast <2 x double> [[B]] to <2 x i64>
+// LLVM:    [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
+// LLVM:    [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x double>
+// LLVM:    [[VCVT_I_I:%.*]] = fptrunc <2 x double> [[TMP2]] to <2 x float>
+// LLVM:    [[SHUFFLE_I:%.*]] = shufflevector <2 x float> [[A]], <2 x float> 
[[VCVT_I_I]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+// LLVM:    ret <4 x float> [[SHUFFLE_I]]
+  return vcvt_high_f32_f64(a, b);
+}
+
+// LLVM-LABEL: @test_vcvt_f32_f16(
+// CIR-LABEL: @vcvt_f32_f16(
+float32x4_t test_vcvt_f32_f16(float16x4_t a) {
+// CIR:  cir.cast floating
+
+// LLVM-SAME: <4 x half> {{.*}} [[A:%.*]])
+// LLVM:    [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <4 x i16>
+// LLVM:    [[TMP1:%.*]] = bitcast <4 x i16> [[TMP0]] to <8 x i8>
+// LLVM:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half>
+// LLVM:    [[TMP3:%.*]] = fpext <4 x half> [[TMP2]] to <4 x float>
+// LLVM:    ret <4 x float> [[TMP3]]
+  return vcvt_f32_f16(a);
+}
+
+// LLVM-LABEL: @test_vcvt_high_f32_f16(
+// CIR-LABEL: @vcvt_high_f32_f16(
+float32x4_t test_vcvt_high_f32_f16(float16x8_t a) {
+// CIR: cir.call @vget_high_f16
+// CIR:  cir.call @vcvt_f32_f16
+
+// LLVM-SAME: <8 x half> {{.*}} [[A:%.*]])
+// LLVM:    [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> 
[[A]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+// LLVM:    [[TMP0:%.*]] = bitcast <4 x half> [[SHUFFLE_I]] to <4 x i16>
+// LLVM:    [[TMP1:%.*]] = bitcast <4 x i16> [[TMP0]] to <8 x i8>
+// LLVM:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half>
+// LLVM:    [[TMP3:%.*]] = fpext <4 x half> [[TMP2]] to <4 x float>
+// LLVM:    ret <4 x float> [[TMP3]]
+  return vcvt_high_f32_f16(a);
+}
+
+// LLVM-LABEL: @test_vcvt_f64_f32(
+// CIR-LABEL: @vcvt_f64_f32(
+float64x2_t test_vcvt_f64_f32(float32x2_t a) {
+// CIR:  cir.cast floating
+
+// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]])
+// LLVM:    [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
+// LLVM:    [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
+// LLVM:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
+// LLVM:    [[VCVT_I:%.*]] = fpext <2 x float> [[TMP2]] to <2 x double>
+// LLVM:    ret <2 x double> [[VCVT_I]]
+  return vcvt_f64_f32(a);
+}
+
+// LLVM-LABEL: @test_vcvt_high_f64_f32(
+// CIR-LABEL: @vcvt_high_f64_f32(
+float64x2_t test_vcvt_high_f64_f32(float32x4_t a) {
+// CIR: cir.call @vget_high_f32
+// CIR:  cir.call @vcvt_f64_f32
+
+// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]])
+// LLVM:    [[SHUFFLE_I:%.*]] = shufflevector <4 x float> [[A]], <4 x float> 
[[A]], <2 x i32> <i32 2, i32 3>
+// LLVM:    [[TMP0:%.*]] = bitcast <2 x float> [[SHUFFLE_I]] to <2 x i32>
+// LLVM:    [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
+// LLVM:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
+// LLVM:    [[VCVT_I_I:%.*]] = fpext <2 x float> [[TMP2]] to <2 x double>
+// LLVM:    ret <2 x double> [[VCVT_I_I]]
+  return vcvt_high_f64_f32(a);
+}
+
+// LLVM-LABEL: @test_vcvtx_f32_f64(
+// CIR-LABEL: @vcvtx_f32_f64(
+float32x2_t test_vcvtx_f32_f64(float64x2_t a) {
+// CIR:  cir.call_llvm_intrinsic "aarch64.neon.fcvtxn"
+
+// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]])
+// LLVM:    [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
+// LLVM:    [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
+// LLVM:    [[VCVTX_F32_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x double>
+// LLVM:    [[VCVTX_F32_V1_I:%.*]] = call <2 x float> 
@llvm.aarch64.neon.fcvtxn.v2f32.v2f64(<2 x double> [[VCVTX_F32_V_I]])
+// LLVM:    ret <2 x float> [[VCVTX_F32_V1_I]]
+  return vcvtx_f32_f64(a);
+}
+
+// LLVM-LABEL: @test_vcvtxd_f32_f64
+// CIR-LABEL: @vcvtxd_f32_f64
+float32_t test_vcvtxd_f32_f64(float64_t a) {
+// CIR:  cir.call_llvm_intrinsic "aarch64.sisd.fcvtxn"
+
+// LLVM-SAME: (double {{.*}} [[A:%.*]])
+// LLVM:    [[VCVTXD_F32_F64_I:%.*]] = call float 
@llvm.aarch64.sisd.fcvtxn(double [[A]])
+// LLVM:    ret float [[VCVTXD_F32_F64_I]]
+  return (float32_t)vcvtxd_f32_f64(a);
+}
+
+// LLVM-LABEL: @test_vcvtx_high_f32_f64(
+// CIR-LABEL: @vcvtx_high_f32_f64(
+float32x4_t test_vcvtx_high_f32_f64(float32x2_t a, float64x2_t b) {
+// CIR: cir.call @vcvtx_f32_f64
+// CIR: cir.call @vcombine_f32
+
+// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]], <2 x double> {{.*}} [[B:%.*]])
+// LLVM:    [[TMP0:%.*]] = bitcast <2 x double> [[B]] to <2 x i64>
+// LLVM:    [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
+// LLVM:    [[VCVTX_F32_V_I_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x 
double>
+// LLVM:    [[VCVTX_F32_V1_I_I:%.*]] = call <2 x float> 
@llvm.aarch64.neon.fcvtxn.v2f32.v2f64(<2 x double> [[VCVTX_F32_V_I_I]])
+// LLVM:    [[SHUFFLE_I:%.*]] = shufflevector <2 x float> [[A]], <2 x float> 
[[VCVTX_F32_V1_I_I]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+// LLVM:    ret <4 x float> [[SHUFFLE_I]]
+  return vcvtx_high_f32_f64(a, b);
+}
+
 //===------------------------------------------------------===//
 // 2.1.3.2.3 Vector shift right and accumulate
 // 
https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#vector-shift-right-and-accumulate

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to