llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-arm

Author: Kieran B (kieroxide)

<details>
<summary>Changes</summary>

- Add ImmCheckShiftLeftLong to allow checking of [0..((elt/2) -1)] range checks
- Add immediate range checks in vector-shift-left.c
- Update stale intrinsic tests for vcvt_f32_bf16 and vshll_n
- Add GIsel patterns so VCVT_F32_BF16 lowers to the correct ACLE specified 
instruction

The fixed immediate range caused a problem with the VCVT_F32_BF16 instrinic as 
it used vshll_n with an illegal range immediate of 16. I split this instruction 
into a widen (vmovl) then a shift (vshl_n) producing the same result.

Both A64/A32 lower to the vshll/shll 16 widen-shift instruction in asm as 
defined in ACLE. Tests for the vshll_n fold can be found in vshll.ll (A32) and 
arm64-vshift.ll (A64)

---

Patch is 45.86 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/212459.diff


9 Files Affected:

- (modified) clang/include/clang/Basic/arm_immcheck_incl.td (+22-21) 
- (modified) clang/include/clang/Basic/arm_neon.td (+10-9) 
- (modified) clang/lib/Sema/SemaARM.cpp (+5) 
- (modified) clang/test/CodeGen/AArch64/neon-misc.c (+24-24) 
- (modified) clang/test/CodeGen/arm-bf16-convert-intrinsics.c (+54-36) 
- (modified) clang/test/Sema/aarch64-neon-immediate-ranges/vector-shift-left.c 
(+12-33) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+5) 
- (modified) llvm/test/CodeGen/AArch64/arm64-vcvt_f.ll (+54) 
- (modified) llvm/test/CodeGen/AArch64/arm64-vshift.ll (+4-10) 


``````````diff
diff --git a/clang/include/clang/Basic/arm_immcheck_incl.td 
b/clang/include/clang/Basic/arm_immcheck_incl.td
index 6892b8299771b..87bc83e89aa10 100644
--- a/clang/include/clang/Basic/arm_immcheck_incl.td
+++ b/clang/include/clang/Basic/arm_immcheck_incl.td
@@ -11,27 +11,28 @@ def ImmCheckExtract             : ImmCheckType<2>;  // 
0..(2048/sizeinbits(elt)
 def ImmCheckShiftRight          : ImmCheckType<3>;  // 1..sizeinbits(elt)
 def ImmCheckShiftRightNarrow    : ImmCheckType<4>;  // 1..sizeinbits(elt)/2
 def ImmCheckShiftLeft           : ImmCheckType<5>;  // 0..(sizeinbits(elt) - 1)
-def ImmCheck0_7                 : ImmCheckType<6>;  // 0..7
-def ImmCheckLaneIndex           : ImmCheckType<7>;  // 
0..(container_size/(sizeinbits(elt)) - 1)
-def ImmCheckCvt                 : ImmCheckType<8>;  // 1..sizeinbits(elt) 
(same as ShiftRight)
-def ImmCheckLaneIndexCompRotate : ImmCheckType<9>;  // 
0..(container_size/(2*sizeinbits(elt)) - 1)
-def ImmCheckLaneIndexDot        : ImmCheckType<10>; // 
0..(container_size/(4*sizeinbits(elt)) - 1)
-def ImmCheckComplexRot90_270    : ImmCheckType<11>; // [90,270]
-def ImmCheckComplexRotAll90     : ImmCheckType<12>; // [0, 90, 180,270]
-def ImmCheck0_13                : ImmCheckType<13>; // 0..13
-def ImmCheck0_1                 : ImmCheckType<14>; // 0..1
-def ImmCheck0_2                 : ImmCheckType<15>; // 0..2
-def ImmCheck0_3                 : ImmCheckType<16>; // 0..3
-def ImmCheck0_0                 : ImmCheckType<17>; // 0..0
-def ImmCheck0_15                : ImmCheckType<18>; // 0..15
-def ImmCheck0_255               : ImmCheckType<19>; // 0..255
-def ImmCheck2_4_Mul2            : ImmCheckType<20>; // 2, 4
-def ImmCheck1_1                 : ImmCheckType<21>; // 1..1
-def ImmCheck1_3                 : ImmCheckType<22>; // 1..3
-def ImmCheck1_7                 : ImmCheckType<23>; // 1..7
-def ImmCheck1_32                : ImmCheckType<24>; // 1..32
-def ImmCheck1_64                : ImmCheckType<25>; // 1..64
-def ImmCheck0_63                : ImmCheckType<26>; // 0..63
+def ImmCheckShiftLeftLong       : ImmCheckType<6>;  // 0..(sizeinbits(elt)/2) 
- 1)
+def ImmCheck0_7                 : ImmCheckType<7>;  // 0..7
+def ImmCheckLaneIndex           : ImmCheckType<8>;  // 
0..(container_size/(sizeinbits(elt)) - 1)
+def ImmCheckCvt                 : ImmCheckType<9>;  // 1..sizeinbits(elt) 
(same as ShiftRight)
+def ImmCheckLaneIndexCompRotate : ImmCheckType<10>; // 
0..(container_size/(2*sizeinbits(elt)) - 1)
+def ImmCheckLaneIndexDot        : ImmCheckType<11>; // 
0..(container_size/(4*sizeinbits(elt)) - 1)
+def ImmCheckComplexRot90_270    : ImmCheckType<12>; // [90,270]
+def ImmCheckComplexRotAll90     : ImmCheckType<13>; // [0, 90, 180,270]
+def ImmCheck0_13                : ImmCheckType<14>; // 0..13
+def ImmCheck0_1                 : ImmCheckType<15>; // 0..1
+def ImmCheck0_2                 : ImmCheckType<16>; // 0..2
+def ImmCheck0_3                 : ImmCheckType<17>; // 0..3
+def ImmCheck0_0                 : ImmCheckType<18>; // 0..0
+def ImmCheck0_15                : ImmCheckType<19>; // 0..15
+def ImmCheck0_255               : ImmCheckType<20>; // 0..255
+def ImmCheck2_4_Mul2            : ImmCheckType<21>; // 2, 4
+def ImmCheck1_1                 : ImmCheckType<22>; // 1..1
+def ImmCheck1_3                 : ImmCheckType<23>; // 1..3
+def ImmCheck1_7                 : ImmCheckType<24>; // 1..7
+def ImmCheck1_32                : ImmCheckType<25>; // 1..32
+def ImmCheck1_64                : ImmCheckType<26>; // 1..64
+def ImmCheck0_63                : ImmCheckType<27>; // 0..63
 
 class ImmCheck<int immArgIdx, ImmCheckType kind, int typeArgIdx = -1> {
   // Parameter index of immediate argument to be verified
diff --git a/clang/include/clang/Basic/arm_neon.td 
b/clang/include/clang/Basic/arm_neon.td
index 041a420875290..e7008b39f202d 100644
--- a/clang/include/clang/Basic/arm_neon.td
+++ b/clang/include/clang/Basic/arm_neon.td
@@ -251,9 +251,10 @@ def OP_BFMLALT_LN
           (dup_typed $p1, (call "vget_lane", $p2, $p3)))>;
 
 def OP_VCVT_F32_BF16
-    : Op<(bitcast "R",
-          (call "vshll_n", (bitcast "uint16x4_t", $p0),
-                           (literal "int32_t", "16")))>;
+     : Op<(bitcast "R",
+          (call "vshl_n",
+            (call "vmovl", (bitcast "uint16x4_t", $p0)),
+            (literal "int32_t", "16")))>;
 def OP_VCVT_F32_BF16_LO
     : Op<(call "vcvt_f32_bf16", (call "vget_low", $p0))>;
 def OP_VCVT_F32_BF16_HI
@@ -432,13 +433,13 @@ def VRSHRN_N   : IInst<"vrshrn_n", "<QI", "silUsUiUl",
 def VQRSHRN_N  : SInst<"vqrshrn_n", "<QI", "silUsUiUl",
                       [ImmCheck<1, ImmCheckShiftRight>]>;
 
-// Widening left-shifts should have a range of 0..(sizeinbits(arg)-1).
-// This polymorphic builtin is supplied the wider return type as it's 
overloaded
-// base type, so the range here is actually 0..(sizeinbits(arg)*2).
-// This cannot be rectified currently due to a use of vshll_n_s16 with an
-// out-of-bounds immediate in the defintiion of vcvt_f32_bf16.
+// Widening left-shifts should have an immediate range of 
0..(sizeinbits(arg)-1).
+// However, as the overloaded type code that is supplied to a polymorphic 
builtin
+// is that of the return type (twice as wide as the argument in this case), 
using
+// ImmCheckShiftLeft would return in an upper bound of ((sizeinbits(arg)*2)-1).
+// ImmCheckShiftLeftLong produces the correct behavior here.
 def VSHLL_N    : SInst<"vshll_n", "(>Q).I", "csiUcUsUi",
-                      [ImmCheck<1, ImmCheckShiftLeft>]>;
+                      [ImmCheck<1, ImmCheckShiftLeftLong>]>;
 
 
////////////////////////////////////////////////////////////////////////////////
 // E.3.13 Shifts with insert
diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index 5e7504fab416d..d801ff17ce2f4 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -452,6 +452,11 @@ bool SemaARM::CheckImmediateArg(CallExpr *TheCall, 
unsigned CheckTy,
     if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, EltBitWidth - 1))
       return true;
     break;
+  case ImmCheckType::ImmCheckShiftLeftLong:
+    if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0,
+                                        (EltBitWidth / 2) - 1))
+      return true;
+    break;
   case ImmCheckType::ImmCheckLaneIndex:
     if (SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0,
                                         (ContainerBitWidth / EltBitWidth) - 1))
diff --git a/clang/test/CodeGen/AArch64/neon-misc.c 
b/clang/test/CodeGen/AArch64/neon-misc.c
index 308718fd1bedf..e9e17b2fe407a 100644
--- a/clang/test/CodeGen/AArch64/neon-misc.c
+++ b/clang/test/CodeGen/AArch64/neon-misc.c
@@ -2451,11 +2451,11 @@ uint32x4_t test_vqmovn_high_u64(uint32x2_t a, 
uint64x2_t b) {
 // CHECK-SAME: <8 x i8> noundef [[A:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[TMP0:%.*]] = sext <8 x i8> [[A]] to <8 x i16>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <8 x i16> [[TMP0]], splat (i16 8)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <8 x i16> [[TMP0]], splat (i16 7)
 // CHECK-NEXT:    ret <8 x i16> [[VSHLL_N]]
 //
 int16x8_t test_vshll_n_s8(int8x8_t a) {
-  return vshll_n_s8(a, 8);
+  return vshll_n_s8(a, 7);
 }
 
 // CHECK-LABEL: define dso_local <4 x i32> @test_vshll_n_s16(
@@ -2464,11 +2464,11 @@ int16x8_t test_vshll_n_s8(int8x8_t a) {
 // CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
 // CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
 // CHECK-NEXT:    [[TMP2:%.*]] = sext <4 x i16> [[TMP1]] to <4 x i32>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <4 x i32> [[TMP2]], splat (i32 16)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <4 x i32> [[TMP2]], splat (i32 15)
 // CHECK-NEXT:    ret <4 x i32> [[VSHLL_N]]
 //
 int32x4_t test_vshll_n_s16(int16x4_t a) {
-  return vshll_n_s16(a, 16);
+  return vshll_n_s16(a, 15);
 }
 
 // CHECK-LABEL: define dso_local <2 x i64> @test_vshll_n_s32(
@@ -2477,22 +2477,22 @@ int32x4_t test_vshll_n_s16(int16x4_t a) {
 // 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:    [[TMP2:%.*]] = sext <2 x i32> [[TMP1]] to <2 x i64>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <2 x i64> [[TMP2]], splat (i64 32)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <2 x i64> [[TMP2]], splat (i64 31)
 // CHECK-NEXT:    ret <2 x i64> [[VSHLL_N]]
 //
 int64x2_t test_vshll_n_s32(int32x2_t a) {
-  return vshll_n_s32(a, 32);
+  return vshll_n_s32(a, 31);
 }
 
 // CHECK-LABEL: define dso_local <8 x i16> @test_vshll_n_u8(
 // CHECK-SAME: <8 x i8> noundef [[A:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <8 x i8> [[A]] to <8 x i16>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <8 x i16> [[TMP0]], splat (i16 8)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <8 x i16> [[TMP0]], splat (i16 7)
 // CHECK-NEXT:    ret <8 x i16> [[VSHLL_N]]
 //
 uint16x8_t test_vshll_n_u8(uint8x8_t a) {
-  return vshll_n_u8(a, 8);
+  return vshll_n_u8(a, 7);
 }
 
 // CHECK-LABEL: define dso_local <4 x i32> @test_vshll_n_u16(
@@ -2501,11 +2501,11 @@ uint16x8_t test_vshll_n_u8(uint8x8_t a) {
 // CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
 // CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
 // CHECK-NEXT:    [[TMP2:%.*]] = zext <4 x i16> [[TMP1]] to <4 x i32>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <4 x i32> [[TMP2]], splat (i32 16)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <4 x i32> [[TMP2]], splat (i32 15)
 // CHECK-NEXT:    ret <4 x i32> [[VSHLL_N]]
 //
 uint32x4_t test_vshll_n_u16(uint16x4_t a) {
-  return vshll_n_u16(a, 16);
+  return vshll_n_u16(a, 15);
 }
 
 // CHECK-LABEL: define dso_local <2 x i64> @test_vshll_n_u32(
@@ -2514,11 +2514,11 @@ uint32x4_t test_vshll_n_u16(uint16x4_t a) {
 // 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:    [[TMP2:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <2 x i64> [[TMP2]], splat (i64 32)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <2 x i64> [[TMP2]], splat (i64 31)
 // CHECK-NEXT:    ret <2 x i64> [[VSHLL_N]]
 //
 uint64x2_t test_vshll_n_u32(uint32x2_t a) {
-  return vshll_n_u32(a, 32);
+  return vshll_n_u32(a, 31);
 }
 
 // CHECK-LABEL: define dso_local <8 x i16> @test_vshll_high_n_s8(
@@ -2526,11 +2526,11 @@ uint64x2_t test_vshll_n_u32(uint32x2_t a) {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[SHUFFLE_I:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> 
[[A]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
 // CHECK-NEXT:    [[TMP0:%.*]] = sext <8 x i8> [[SHUFFLE_I]] to <8 x i16>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <8 x i16> [[TMP0]], splat (i16 8)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <8 x i16> [[TMP0]], splat (i16 7)
 // CHECK-NEXT:    ret <8 x i16> [[VSHLL_N]]
 //
 int16x8_t test_vshll_high_n_s8(int8x16_t a) {
-  return vshll_high_n_s8(a, 8);
+  return vshll_high_n_s8(a, 7);
 }
 
 // CHECK-LABEL: define dso_local <4 x i32> @test_vshll_high_n_s16(
@@ -2540,11 +2540,11 @@ int16x8_t test_vshll_high_n_s8(int8x16_t a) {
 // CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to <8 x i8>
 // CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
 // CHECK-NEXT:    [[TMP2:%.*]] = sext <4 x i16> [[TMP1]] to <4 x i32>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <4 x i32> [[TMP2]], splat (i32 16)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <4 x i32> [[TMP2]], splat (i32 15)
 // CHECK-NEXT:    ret <4 x i32> [[VSHLL_N]]
 //
 int32x4_t test_vshll_high_n_s16(int16x8_t a) {
-  return vshll_high_n_s16(a, 16);
+  return vshll_high_n_s16(a, 15);
 }
 
 // CHECK-LABEL: define dso_local <2 x i64> @test_vshll_high_n_s32(
@@ -2554,11 +2554,11 @@ int32x4_t test_vshll_high_n_s16(int16x8_t a) {
 // CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to <8 x i8>
 // CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
 // CHECK-NEXT:    [[TMP2:%.*]] = sext <2 x i32> [[TMP1]] to <2 x i64>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <2 x i64> [[TMP2]], splat (i64 32)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <2 x i64> [[TMP2]], splat (i64 31)
 // CHECK-NEXT:    ret <2 x i64> [[VSHLL_N]]
 //
 int64x2_t test_vshll_high_n_s32(int32x4_t a) {
-  return vshll_high_n_s32(a, 32);
+  return vshll_high_n_s32(a, 31);
 }
 
 // CHECK-LABEL: define dso_local <8 x i16> @test_vshll_high_n_u8(
@@ -2566,11 +2566,11 @@ int64x2_t test_vshll_high_n_s32(int32x4_t a) {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[SHUFFLE_I:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> 
[[A]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <8 x i8> [[SHUFFLE_I]] to <8 x i16>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <8 x i16> [[TMP0]], splat (i16 8)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <8 x i16> [[TMP0]], splat (i16 7)
 // CHECK-NEXT:    ret <8 x i16> [[VSHLL_N]]
 //
 uint16x8_t test_vshll_high_n_u8(uint8x16_t a) {
-  return vshll_high_n_u8(a, 8);
+  return vshll_high_n_u8(a, 7);
 }
 
 // CHECK-LABEL: define dso_local <4 x i32> @test_vshll_high_n_u16(
@@ -2580,11 +2580,11 @@ uint16x8_t test_vshll_high_n_u8(uint8x16_t a) {
 // CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to <8 x i8>
 // CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
 // CHECK-NEXT:    [[TMP2:%.*]] = zext <4 x i16> [[TMP1]] to <4 x i32>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <4 x i32> [[TMP2]], splat (i32 16)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <4 x i32> [[TMP2]], splat (i32 15)
 // CHECK-NEXT:    ret <4 x i32> [[VSHLL_N]]
 //
 uint32x4_t test_vshll_high_n_u16(uint16x8_t a) {
-  return vshll_high_n_u16(a, 16);
+  return vshll_high_n_u16(a, 15);
 }
 
 // CHECK-LABEL: define dso_local <2 x i64> @test_vshll_high_n_u32(
@@ -2594,11 +2594,11 @@ uint32x4_t test_vshll_high_n_u16(uint16x8_t a) {
 // CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to <8 x i8>
 // CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
 // CHECK-NEXT:    [[TMP2:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
-// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <2 x i64> [[TMP2]], splat (i64 32)
+// CHECK-NEXT:    [[VSHLL_N:%.*]] = shl <2 x i64> [[TMP2]], splat (i64 31)
 // CHECK-NEXT:    ret <2 x i64> [[VSHLL_N]]
 //
 uint64x2_t test_vshll_high_n_u32(uint32x4_t a) {
-  return vshll_high_n_u32(a, 32);
+  return vshll_high_n_u32(a, 31);
 }
 
 // CHECK-LABEL: define dso_local <4 x half> @test_vcvt_f16_f32(
diff --git a/clang/test/CodeGen/arm-bf16-convert-intrinsics.c 
b/clang/test/CodeGen/arm-bf16-convert-intrinsics.c
index 8a1ef2441b39d..256c681db3b3f 100644
--- a/clang/test/CodeGen/arm-bf16-convert-intrinsics.c
+++ b/clang/test/CodeGen/arm-bf16-convert-intrinsics.c
@@ -27,20 +27,24 @@
 // CHECK-A64-NEXT:    [[TMP0:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <4 x 
i16>
 // CHECK-A64-NEXT:    [[TMP1:%.*]] = bitcast <4 x i16> [[TMP0]] to <8 x i8>
 // CHECK-A64-NEXT:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
-// CHECK-A64-NEXT:    [[TMP3:%.*]] = zext <4 x i16> [[TMP2]] to <4 x i32>
-// CHECK-A64-NEXT:    [[VSHLL_N_I:%.*]] = shl <4 x i32> [[TMP3]], splat (i32 
16)
-// CHECK-A64-NEXT:    [[TMP4:%.*]] = bitcast <4 x i32> [[VSHLL_N_I]] to <4 x 
float>
-// CHECK-A64-NEXT:    ret <4 x float> [[TMP4]]
+// CHECK-A64-NEXT:    [[VMOVL_I:%.*]] = zext <4 x i16> [[TMP2]] to <4 x i32>
+// CHECK-A64-NEXT:    [[TMP3:%.*]] = bitcast <4 x i32> [[VMOVL_I]] to <16 x i8>
+// CHECK-A64-NEXT:    [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x i32>
+// CHECK-A64-NEXT:    [[VSHL_N_I:%.*]] = shl <4 x i32> [[TMP4]], splat (i32 16)
+// CHECK-A64-NEXT:    [[TMP5:%.*]] = bitcast <4 x i32> [[VSHL_N_I]] to <4 x 
float>
+// CHECK-A64-NEXT:    ret <4 x float> [[TMP5]]
 //
 // CHECK-A32-HARDFP-LABEL: @test_vcvt_f32_bf16(
 // CHECK-A32-HARDFP-NEXT:  entry:
 // CHECK-A32-HARDFP-NEXT:    [[TMP0:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to 
<4 x i16>
 // CHECK-A32-HARDFP-NEXT:    [[TMP1:%.*]] = bitcast <4 x i16> [[TMP0]] to <8 x 
i8>
 // CHECK-A32-HARDFP-NEXT:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x 
i16>
-// CHECK-A32-HARDFP-NEXT:    [[TMP3:%.*]] = zext <4 x i16> [[TMP2]] to <4 x 
i32>
-// CHECK-A32-HARDFP-NEXT:    [[VSHLL_N_I:%.*]] = shl <4 x i32> [[TMP3]], splat 
(i32 16)
-// CHECK-A32-HARDFP-NEXT:    [[TMP4:%.*]] = bitcast <4 x i32> [[VSHLL_N_I]] to 
<4 x float>
-// CHECK-A32-HARDFP-NEXT:    ret <4 x float> [[TMP4]]
+// CHECK-A32-HARDFP-NEXT:    [[VMOVL_I:%.*]] = zext <4 x i16> [[TMP2]] to <4 x 
i32>
+// CHECK-A32-HARDFP-NEXT:    [[TMP3:%.*]] = bitcast <4 x i32> [[VMOVL_I]] to 
<16 x i8>
+// CHECK-A32-HARDFP-NEXT:    [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x 
i32>
+// CHECK-A32-HARDFP-NEXT:    [[VSHL_N_I:%.*]] = shl <4 x i32> [[TMP4]], splat 
(i32 16)
+// CHECK-A32-HARDFP-NEXT:    [[TMP5:%.*]] = bitcast <4 x i32> [[VSHL_N_I]] to 
<4 x float>
+// CHECK-A32-HARDFP-NEXT:    ret <4 x float> [[TMP5]]
 //
 // CHECK-A32-SOFTFP-LABEL: @test_vcvt_f32_bf16(
 // CHECK-A32-SOFTFP-NEXT:  entry:
@@ -50,10 +54,12 @@
 // CHECK-A32-SOFTFP-NEXT:    [[TMP3:%.*]] = bitcast <4 x bfloat> [[TMP2]] to 
<4 x i16>
 // CHECK-A32-SOFTFP-NEXT:    [[TMP4:%.*]] = bitcast <4 x i16> [[TMP3]] to <8 x 
i8>
 // CHECK-A32-SOFTFP-NEXT:    [[TMP5:%.*]] = bitcast <8 x i8> [[TMP4]] to <4 x 
i16>
-// CHECK-A32-SOFTFP-NEXT:    [[TMP6:%.*]] = zext <4 x i16> [[TMP5]] to <4 x 
i32>
-// CHECK-A32-SOFTFP-NEXT:    [[VSHLL_N_I:%.*]] = shl <4 x i32> [[TMP6]], splat 
(i32 16)
-// CHECK-A32-SOFTFP-NEXT:    [[TMP7:%.*]] = bitcast <4 x i32> [[VSHLL_N_I]] to 
<4 x float>
-// CHECK-A32-SOFTFP-NEXT:    ret <4 x float> [[TMP7]]
+// CHECK-A32-SOFTFP-NEXT:    [[VMOVL_I:%.*]] = zext <4 x i16> [[TMP5]] to <4 x 
i32>
+// CHECK-A32-SOFTFP-NEXT:    [[TMP6:%.*]] = bitcast <4 x i32> [[VMOVL_I]] to 
<16 x i8>
+// CHECK-A32-SOFTFP-NEXT:    [[TMP7:%.*]] = bitcast <16 x i8> [[TMP6]] to <4 x 
i32>
+// CHECK-A32-SOFTFP-NEXT:    [[VSHL_N_I:%.*]] = shl <4 x i32> [[TMP7]], splat 
(i32 16)
+// CHECK-A32-SOFTFP-NEXT:    [[TMP8:%.*]] = bitcast <4 x i32> [[VSHL_N_I]] to 
<4 x float>
+// CHECK-A32-SOFTFP-NEXT:    ret <4 x float> [[TMP8]]
 //
 float32x4_t test_vcvt_f32_bf16(bfloat16x4_t a) {
   return vcvt_f32_bf16(a);
@@ -65,10 +71,12 @@ float32x4_t test_vcvt_f32_bf16(bfloat16x4_t a) {
 // CHECK-A64-NEXT:    [[TMP0:%.*]] = bitcast <4 x bfloat> [[SHUFFLE_I]] to <4 
x i16>
 // CHECK-A64-NEXT:    [[TMP1:%.*]] = bitcast <4 x i16> [[TMP0]] to <8 x i8>
 // CHECK-A64-NEXT:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
-// CHECK-A64-NEXT:    [[TMP3:%.*]] = zext <4 x i16> [[TMP2]] to <4 x i32>
-// CHECK-A64-NEXT:    [[VSHLL_N_I_I:%.*]] = shl <4 x i32> [[TMP3]], splat (i32 
16)
-// CHECK-A64-NEXT:    [[TMP4:%.*]] = bitcast <4 x i32> [[VSHLL_N_I_I]] to <4 x 
float>
-// CHECK-A64-NEXT:    ret <4 x float> [[TMP4]]
+// CHECK-A64-NEXT:    [[VMOVL_I:%.*]] = zext <4 x i16> [[TMP2]] to <4 x i32>
+// CHECK-A64-NEXT:    [[TMP3:%.*]] = bitcast <4 x i32> [[VMOVL_I]] to <16 x i8>
+// CHECK-A64-NEXT:    [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x i32>
+// CHECK-A64-NEXT:    [[VSHL_N_I_I:%.*]] = shl <4 x i32> [[TMP4]], splat (i32 
16)
+// CHECK-A64-NEXT:    [[TMP5:%.*]] = bitcast <4 x i32> [[VSHL_N_I_I]] to <4 x 
float>
+// CHECK-A64-NEXT:    ret <4 x float> [[TMP5]]
 //
 // CHECK-A32-HARDFP-LABEL: @test_vcvtq_low_f32_bf16(
 // CHECK-A32-HARDFP-NEXT:  entry:
@@ -76,10 +84,12 @@ float32x4_t test_vcvt_f32_bf16(bfloat16x4_t a) {
 // CHECK-A32-HARDFP-NEXT:    [[TMP0:%.*]] = bitcast <4 x bfloat> [[SHUFFLE_I]] 
to <4 x i16>
 // CHECK-A32-HARDFP-NEXT:    [[TMP1:%.*]] = bitcast <4 x i16> [[TMP0]] to <8 x 
i8>
 // CHECK-A32-HARDFP-NEXT:    [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x 
i16>
-// CHECK-A32-HARDFP-NEXT:    [[TMP3:%.*]] = zext <4 x i16> [[TMP2]] to <4 x 
i32>
-// CHECK-A32-HARDFP-NEXT:    [[VSHLL_N_I_I:%.*]] = shl <4 x i32> [[TMP3]], 
splat (i32 16)
-// CHECK-A32-HARDFP-NEXT:    [[TMP4:%.*]] = bitcast <4 x i32> [[VSHLL_N_I_I]] 
to <4 x float>
-// CHECK-A32-HARDFP-NEXT:    ret <4 x float> [[TMP4]]
+// CHECK-A32-HARDFP-NEXT:    [[VMOVL_I:%.*]] = zext <4 x i16> [[TMP2]] to <4 x 
i32>
+// CHECK-A32-HARDFP-NEXT:    [[TMP3:%.*]] = bitcast <4 x i32> [[VMOVL_I]] to 
<16 x i8>
+// CHECK-A32-HARDFP-NEXT:    [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x 
i32>
+// CHECK-A32-HARDFP-NEXT:    [[VSHL_N_I_I:%.*]] = shl <4 x i32> [[TMP4]], 
splat (i32 16)
+// CHECK-A32-HARDFP-NEXT:    [[TMP5:%.*]...
[truncated]

``````````

</details>


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

Reply via email to