|  | // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py | 
|  | // RUN: %clang_cc1 -triple aarch64 -target-feature +sve -mvscale-min=4 -mvscale-max=4 -O1 -emit-llvm -o - %s | FileCheck %s | 
|  |  | 
|  | // REQUIRES: aarch64-registered-target | 
|  |  | 
|  | #include <arm_sve.h> | 
|  |  | 
|  | #define N __ARM_FEATURE_SVE_BITS | 
|  |  | 
|  | typedef svint32_t fixed_int32_t __attribute__((arm_sve_vector_bits(N))); | 
|  | typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(N))); | 
|  | typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(N))); | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // Test caller/callee with VLST <-> VLAT | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | // CHECK-LABEL: @sizeless_callee( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    ret <vscale x 4 x i32> [[X:%.*]] | 
|  | // | 
|  | svint32_t sizeless_callee(svint32_t x) { | 
|  | return x; | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: @fixed_caller( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    ret <vscale x 4 x i32> [[X_COERCE:%.*]] | 
|  | // | 
|  | fixed_int32_t fixed_caller(fixed_int32_t x) { | 
|  | return sizeless_callee(x); | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: @fixed_callee( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    ret <vscale x 4 x i32> [[X_COERCE:%.*]] | 
|  | // | 
|  | fixed_int32_t fixed_callee(fixed_int32_t x) { | 
|  | return x; | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: @sizeless_caller( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    ret <vscale x 4 x i32> [[X:%.*]] | 
|  | // | 
|  | svint32_t sizeless_caller(svint32_t x) { | 
|  | return fixed_callee(x); | 
|  | } | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // fixed, fixed | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | // CHECK-LABEL: @call_int32_ff( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]]) | 
|  | // CHECK-NEXT:    [[TMP1:%.*]] = select <vscale x 4 x i1> [[TMP0]], <vscale x 4 x i32> [[OP1_COERCE:%.*]], <vscale x 4 x i32> [[OP2_COERCE:%.*]] | 
|  | // CHECK-NEXT:    ret <vscale x 4 x i32> [[TMP1]] | 
|  | // | 
|  | fixed_int32_t call_int32_ff(svbool_t pg, fixed_int32_t op1, fixed_int32_t op2) { | 
|  | return svsel(pg, op1, op2); | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: @call_float64_ff( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]]) | 
|  | // CHECK-NEXT:    [[TMP1:%.*]] = select <vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP1_COERCE:%.*]], <vscale x 2 x double> [[OP2_COERCE:%.*]] | 
|  | // CHECK-NEXT:    ret <vscale x 2 x double> [[TMP1]] | 
|  | // | 
|  | fixed_float64_t call_float64_ff(svbool_t pg, fixed_float64_t op1, fixed_float64_t op2) { | 
|  | return svsel(pg, op1, op2); | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: @call_bool_ff( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    [[TMP2:%.*]] = select <vscale x 16 x i1> [[PG:%.*]], <vscale x 16 x i1> [[TMP0:%.*]], <vscale x 16 x i1> [[TMP1:%.*]] | 
|  | // CHECK-NEXT:    ret <vscale x 16 x i1> [[TMP2]] | 
|  | // | 
|  | fixed_bool_t call_bool_ff(svbool_t pg, fixed_bool_t op1, fixed_bool_t op2) { | 
|  | return svsel(pg, op1, op2); | 
|  | } | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // fixed, scalable | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | // CHECK-LABEL: @call_int32_fs( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]]) | 
|  | // CHECK-NEXT:    [[TMP1:%.*]] = select <vscale x 4 x i1> [[TMP0]], <vscale x 4 x i32> [[OP1_COERCE:%.*]], <vscale x 4 x i32> [[OP2:%.*]] | 
|  | // CHECK-NEXT:    ret <vscale x 4 x i32> [[TMP1]] | 
|  | // | 
|  | fixed_int32_t call_int32_fs(svbool_t pg, fixed_int32_t op1, svint32_t op2) { | 
|  | return svsel(pg, op1, op2); | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: @call_float64_fs( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]]) | 
|  | // CHECK-NEXT:    [[TMP1:%.*]] = select <vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP1_COERCE:%.*]], <vscale x 2 x double> [[OP2:%.*]] | 
|  | // CHECK-NEXT:    ret <vscale x 2 x double> [[TMP1]] | 
|  | // | 
|  | fixed_float64_t call_float64_fs(svbool_t pg, fixed_float64_t op1, svfloat64_t op2) { | 
|  | return svsel(pg, op1, op2); | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: @call_bool_fs( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    [[TMP1:%.*]] = select <vscale x 16 x i1> [[PG:%.*]], <vscale x 16 x i1> [[TMP0:%.*]], <vscale x 16 x i1> [[OP2:%.*]] | 
|  | // CHECK-NEXT:    ret <vscale x 16 x i1> [[TMP1]] | 
|  | // | 
|  | fixed_bool_t call_bool_fs(svbool_t pg, fixed_bool_t op1, svbool_t op2) { | 
|  | return svsel(pg, op1, op2); | 
|  | } | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // scalable, scalable | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | // CHECK-LABEL: @call_int32_ss( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]]) | 
|  | // CHECK-NEXT:    [[TMP1:%.*]] = select <vscale x 4 x i1> [[TMP0]], <vscale x 4 x i32> [[OP1:%.*]], <vscale x 4 x i32> [[OP2:%.*]] | 
|  | // CHECK-NEXT:    ret <vscale x 4 x i32> [[TMP1]] | 
|  | // | 
|  | fixed_int32_t call_int32_ss(svbool_t pg, svint32_t op1, svint32_t op2) { | 
|  | return svsel(pg, op1, op2); | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: @call_float64_ss( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]]) | 
|  | // CHECK-NEXT:    [[TMP1:%.*]] = select <vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP1:%.*]], <vscale x 2 x double> [[OP2:%.*]] | 
|  | // CHECK-NEXT:    ret <vscale x 2 x double> [[TMP1]] | 
|  | // | 
|  | fixed_float64_t call_float64_ss(svbool_t pg, svfloat64_t op1, svfloat64_t op2) { | 
|  | return svsel(pg, op1, op2); | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: @call_bool_ss( | 
|  | // CHECK-NEXT:  entry: | 
|  | // CHECK-NEXT:    [[TMP0:%.*]] = select <vscale x 16 x i1> [[PG:%.*]], <vscale x 16 x i1> [[OP1:%.*]], <vscale x 16 x i1> [[OP2:%.*]] | 
|  | // CHECK-NEXT:    ret <vscale x 16 x i1> [[TMP0]] | 
|  | // | 
|  | fixed_bool_t call_bool_ss(svbool_t pg, svbool_t op1, svbool_t op2) { | 
|  | return svsel(pg, op1, op2); | 
|  | } |