|
| 1 | +// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -flax-vector-conversions=all -Werror -emit-llvm -o - %s | FileCheck %s |
| 2 | +// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -flax-vector-conversions=all -verify -fsyntax-only -DERROR_CHECK %s |
| 3 | + |
| 4 | +typedef signed short int16_t; |
| 5 | +typedef signed int int32_t; |
| 6 | +typedef signed long long int64_t; |
| 7 | +typedef unsigned short uint16_t; |
| 8 | +typedef unsigned int uint32_t; |
| 9 | +typedef unsigned long long uint64_t; |
| 10 | + |
| 11 | +typedef __attribute__((neon_vector_type(8), __clang_arm_mve_strict_polymorphism)) int16_t int16x8_t; |
| 12 | +typedef __attribute__((neon_vector_type(4), __clang_arm_mve_strict_polymorphism)) int32_t int32x4_t; |
| 13 | +typedef __attribute__((neon_vector_type(2), __clang_arm_mve_strict_polymorphism)) int64_t int64x2_t; |
| 14 | +typedef __attribute__((neon_vector_type(8), __clang_arm_mve_strict_polymorphism)) uint16_t uint16x8_t; |
| 15 | +typedef __attribute__((neon_vector_type(4), __clang_arm_mve_strict_polymorphism)) uint32_t uint32x4_t; |
| 16 | +typedef __attribute__((neon_vector_type(2), __clang_arm_mve_strict_polymorphism)) uint64_t uint64x2_t; |
| 17 | + |
| 18 | +__attribute__((overloadable)) |
| 19 | +int overload(int16x8_t x, int16_t y); // expected-note {{candidate function}} |
| 20 | +__attribute__((overloadable)) |
| 21 | +int overload(int32x4_t x, int32_t y); // expected-note {{candidate function}} |
| 22 | +__attribute__((overloadable)) |
| 23 | +int overload(uint16x8_t x, uint16_t y); // expected-note {{candidate function}} |
| 24 | +__attribute__((overloadable)) |
| 25 | +int overload(uint32x4_t x, uint32_t y); // expected-note {{candidate function}} |
| 26 | + |
| 27 | +int16_t s16; |
| 28 | +int32_t s32; |
| 29 | +uint16_t u16; |
| 30 | +uint32_t u32; |
| 31 | + |
| 32 | +int16x8_t vs16; |
| 33 | +int32x4_t vs32; |
| 34 | +uint16x8_t vu16; |
| 35 | +uint32x4_t vu32; |
| 36 | + |
| 37 | +// ---------------------------------------------------------------------- |
| 38 | +// Simple cases where the types are correctly matched |
| 39 | + |
| 40 | +// CHECK-LABEL: @test_easy_s16( |
| 41 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_int16 |
| 42 | +int test_easy_s16(void) { return overload(vs16, s16); } |
| 43 | + |
| 44 | +// CHECK-LABEL: @test_easy_u16( |
| 45 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_uint16 |
| 46 | +int test_easy_u16(void) { return overload(vu16, u16); } |
| 47 | + |
| 48 | +// CHECK-LABEL: @test_easy_s32( |
| 49 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_int32 |
| 50 | +int test_easy_s32(void) { return overload(vs32, s32); } |
| 51 | + |
| 52 | +// CHECK-LABEL: @test_easy_u32( |
| 53 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_uint32 |
| 54 | +int test_easy_u32(void) { return overload(vu32, u32); } |
| 55 | + |
| 56 | +// ---------------------------------------------------------------------- |
| 57 | +// Do arithmetic on the scalar, and it may get promoted. We still expect the |
| 58 | +// same overloads to be selected if that happens. |
| 59 | + |
| 60 | +// CHECK-LABEL: @test_promote_s16( |
| 61 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_int16 |
| 62 | +int test_promote_s16(void) { return overload(vs16, s16 + 1); } |
| 63 | + |
| 64 | +// CHECK-LABEL: @test_promote_u16( |
| 65 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_uint16 |
| 66 | +int test_promote_u16(void) { return overload(vu16, u16 + 1); } |
| 67 | + |
| 68 | +// CHECK-LABEL: @test_promote_s32( |
| 69 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_int32 |
| 70 | +int test_promote_s32(void) { return overload(vs32, s32 + 1); } |
| 71 | + |
| 72 | +// CHECK-LABEL: @test_promote_u32( |
| 73 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_uint32 |
| 74 | +int test_promote_u32(void) { return overload(vu32, u32 + 1); } |
| 75 | + |
| 76 | +// ---------------------------------------------------------------------- |
| 77 | +// Write a simple integer literal without qualification, and expect |
| 78 | +// the vector type to make it unambiguous which integer type you meant |
| 79 | +// the literal to be. |
| 80 | + |
| 81 | +// CHECK-LABEL: @test_literal_s16( |
| 82 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_int16 |
| 83 | +int test_literal_s16(void) { return overload(vs16, 1); } |
| 84 | + |
| 85 | +// CHECK-LABEL: @test_literal_u16( |
| 86 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_uint16 |
| 87 | +int test_literal_u16(void) { return overload(vu16, 1); } |
| 88 | + |
| 89 | +// CHECK-LABEL: @test_literal_s32( |
| 90 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_int32 |
| 91 | +int test_literal_s32(void) { return overload(vs32, 1); } |
| 92 | + |
| 93 | +// CHECK-LABEL: @test_literal_u32( |
| 94 | +// CHECK: call i32 @_Z8overload{{[a-zA-Z0-9_]+}}_uint32 |
| 95 | +int test_literal_u32(void) { return overload(vu32, 1); } |
| 96 | + |
| 97 | +// ---------------------------------------------------------------------- |
| 98 | +// All of those overload resolutions are supposed to be unambiguous even when |
| 99 | +// lax vector conversion is enabled. Check here that a lax conversion in a |
| 100 | +// different context still works. |
| 101 | +int16x8_t lax_conversion(void) { return vu32; } |
| 102 | + |
| 103 | +// ---------------------------------------------------------------------- |
| 104 | +// Use a vector type that there really _isn't_ any overload for, and |
| 105 | +// make sure that we get a fatal compile error. |
| 106 | + |
| 107 | +#ifdef ERROR_CHECK |
| 108 | +int expect_error(uint64x2_t v) { |
| 109 | + return overload(v, 2); // expected-error {{no matching function for call to 'overload'}} |
| 110 | +} |
| 111 | + |
| 112 | +typedef __attribute__((__clang_arm_mve_strict_polymorphism)) int i; // expected-error {{'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an MVE/NEON vector type}} |
| 113 | +typedef __attribute__((__clang_arm_mve_strict_polymorphism)) int f(); // expected-error {{'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an MVE/NEON vector type}} |
| 114 | +typedef __attribute__((__clang_arm_mve_strict_polymorphism)) struct { uint16x8_t v; } s; // expected-error {{'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an MVE/NEON vector type}} |
| 115 | +#endif |
0 commit comments