1e9f53e40SFangrui Song // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 2e9f53e40SFangrui Song // RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +f -target-feature +d -target-feature +zve64d -mvscale-min=4 -mvscale-max=4 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s 3e9f53e40SFangrui Song 4e9f53e40SFangrui Song // REQUIRES: riscv-registered-target 5e9f53e40SFangrui Song 6e9f53e40SFangrui Song #include <riscv_vector.h> 7e9f53e40SFangrui Song 8e9f53e40SFangrui Song typedef __rvv_int8m1_t vint8m1_t; 9e9f53e40SFangrui Song typedef __rvv_uint8m1_t vuint8m1_t; 10e9f53e40SFangrui Song typedef __rvv_int16m1_t vint16m1_t; 11e9f53e40SFangrui Song typedef __rvv_uint16m1_t vuint16m1_t; 12e9f53e40SFangrui Song typedef __rvv_int32m1_t vint32m1_t; 13e9f53e40SFangrui Song typedef __rvv_uint32m1_t vuint32m1_t; 14e9f53e40SFangrui Song typedef __rvv_int64m1_t vint64m1_t; 15e9f53e40SFangrui Song typedef __rvv_uint64m1_t vuint64m1_t; 16e9f53e40SFangrui Song typedef __rvv_float32m1_t vfloat32m1_t; 17e9f53e40SFangrui Song typedef __rvv_float64m1_t vfloat64m1_t; 18e9f53e40SFangrui Song 19e9f53e40SFangrui Song typedef __rvv_int8m2_t vint8m2_t; 20e9f53e40SFangrui Song typedef __rvv_uint8m2_t vuint8m2_t; 21e9f53e40SFangrui Song typedef __rvv_int16m2_t vint16m2_t; 22e9f53e40SFangrui Song typedef __rvv_uint16m2_t vuint16m2_t; 23e9f53e40SFangrui Song typedef __rvv_int32m2_t vint32m2_t; 24e9f53e40SFangrui Song typedef __rvv_uint32m2_t vuint32m2_t; 25e9f53e40SFangrui Song typedef __rvv_int64m2_t vint64m2_t; 26e9f53e40SFangrui Song typedef __rvv_uint64m2_t vuint64m2_t; 27e9f53e40SFangrui Song typedef __rvv_float32m2_t vfloat32m2_t; 28e9f53e40SFangrui Song typedef __rvv_float64m2_t vfloat64m2_t; 29e9f53e40SFangrui Song 30e9f53e40SFangrui Song typedef __rvv_bool1_t vbool1_t; 31e9f53e40SFangrui Song typedef __rvv_bool4_t vbool4_t; 32e9f53e40SFangrui Song typedef __rvv_bool32_t vbool32_t; 33e9f53e40SFangrui Song 34e9f53e40SFangrui Song typedef vint32m1_t fixed_int32m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen))); 35e9f53e40SFangrui Song typedef vint32m2_t fixed_int32m2_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen * 2))); 36e9f53e40SFangrui Song typedef vint16m4_t fixed_int16m4_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen * 4))); 37e9f53e40SFangrui Song typedef vint8m8_t fixed_int8m8_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen * 8))); 38e9f53e40SFangrui Song typedef vbool1_t fixed_bool1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen))); 39e9f53e40SFangrui Song typedef vbool4_t fixed_bool4_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen/4))); 40e9f53e40SFangrui Song typedef vbool32_t fixed_bool32_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen/32))); 41e9f53e40SFangrui Song 42e9f53e40SFangrui Song fixed_int32m1_t global_vec; 43e9f53e40SFangrui Song fixed_int32m2_t global_vec_m2; 44e9f53e40SFangrui Song fixed_int8m8_t global_vec_int8m8; 45e9f53e40SFangrui Song fixed_int16m4_t global_vec_int16m4; 46e9f53e40SFangrui Song fixed_bool1_t global_bool1; 47e9f53e40SFangrui Song fixed_bool4_t global_bool4; 48e9f53e40SFangrui Song fixed_bool32_t global_bool32; 49e9f53e40SFangrui Song 50e9f53e40SFangrui Song // CHECK-LABEL: @test_bool1( 51e9f53e40SFangrui Song // CHECK-NEXT: entry: 52e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <256 x i8>, align 8 53e9f53e40SFangrui Song // CHECK-NEXT: [[M_ADDR:%.*]] = alloca <vscale x 64 x i1>, align 1 54e9f53e40SFangrui Song // CHECK-NEXT: [[VEC_ADDR:%.*]] = alloca <vscale x 64 x i8>, align 1 55e9f53e40SFangrui Song // CHECK-NEXT: [[MASK:%.*]] = alloca <vscale x 64 x i1>, align 1 56e9f53e40SFangrui Song // CHECK-NEXT: store <vscale x 64 x i1> [[M:%.*]], ptr [[M_ADDR]], align 1 57e9f53e40SFangrui Song // CHECK-NEXT: store <vscale x 64 x i8> [[VEC:%.*]], ptr [[VEC_ADDR]], align 1 58e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load <vscale x 64 x i1>, ptr [[M_ADDR]], align 1 59e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <32 x i8>, ptr @global_bool1, align 8 60*f28e5227SPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v32i8(<vscale x 8 x i8> poison, <32 x i8> [[TMP1]], i64 0) 61e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = bitcast <vscale x 8 x i8> [[CAST_SCALABLE]] to <vscale x 64 x i1> 62e9f53e40SFangrui Song // CHECK-NEXT: [[TMP3:%.*]] = call <vscale x 64 x i1> @llvm.riscv.vmand.nxv64i1.i64(<vscale x 64 x i1> [[TMP0]], <vscale x 64 x i1> [[TMP2]], i64 256) 63e9f53e40SFangrui Song // CHECK-NEXT: store <vscale x 64 x i1> [[TMP3]], ptr [[MASK]], align 1 64e9f53e40SFangrui Song // CHECK-NEXT: [[TMP4:%.*]] = load <vscale x 64 x i1>, ptr [[MASK]], align 1 65e9f53e40SFangrui Song // CHECK-NEXT: [[TMP5:%.*]] = load <vscale x 64 x i8>, ptr [[VEC_ADDR]], align 1 66e9f53e40SFangrui Song // CHECK-NEXT: [[TMP6:%.*]] = load <256 x i8>, ptr @global_vec_int8m8, align 8 67*f28e5227SPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE1:%.*]] = call <vscale x 64 x i8> @llvm.vector.insert.nxv64i8.v256i8(<vscale x 64 x i8> poison, <256 x i8> [[TMP6]], i64 0) 68e9f53e40SFangrui Song // CHECK-NEXT: [[TMP7:%.*]] = call <vscale x 64 x i8> @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i64(<vscale x 64 x i8> poison, <vscale x 64 x i8> [[TMP5]], <vscale x 64 x i8> [[CAST_SCALABLE1]], <vscale x 64 x i1> [[TMP4]], i64 256, i64 3) 69e9f53e40SFangrui Song // CHECK-NEXT: [[CAST_FIXED:%.*]] = call <256 x i8> @llvm.vector.extract.v256i8.nxv64i8(<vscale x 64 x i8> [[TMP7]], i64 0) 70e9f53e40SFangrui Song // CHECK-NEXT: store <256 x i8> [[CAST_FIXED]], ptr [[RETVAL]], align 8 71e9f53e40SFangrui Song // CHECK-NEXT: [[TMP8:%.*]] = load <256 x i8>, ptr [[RETVAL]], align 8 7298e747baSPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE2:%.*]] = call <vscale x 64 x i8> @llvm.vector.insert.nxv64i8.v256i8(<vscale x 64 x i8> poison, <256 x i8> [[TMP8]], i64 0) 73e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 64 x i8> [[CAST_SCALABLE2]] 74e9f53e40SFangrui Song // 75e9f53e40SFangrui Song fixed_int8m8_t test_bool1(vbool1_t m, vint8m8_t vec) { 76e9f53e40SFangrui Song vbool1_t mask = __riscv_vmand(m, global_bool1, __riscv_v_fixed_vlen); 77e9f53e40SFangrui Song return __riscv_vadd(mask, vec, global_vec_int8m8, __riscv_v_fixed_vlen); 78e9f53e40SFangrui Song } 79e9f53e40SFangrui Song 80e9f53e40SFangrui Song // CHECK-LABEL: @test_bool4( 81e9f53e40SFangrui Song // CHECK-NEXT: entry: 82e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <64 x i16>, align 8 83e9f53e40SFangrui Song // CHECK-NEXT: [[M_ADDR:%.*]] = alloca <vscale x 16 x i1>, align 1 84e9f53e40SFangrui Song // CHECK-NEXT: [[VEC_ADDR:%.*]] = alloca <vscale x 16 x i16>, align 2 85e9f53e40SFangrui Song // CHECK-NEXT: [[MASK:%.*]] = alloca <vscale x 16 x i1>, align 1 86e9f53e40SFangrui Song // CHECK-NEXT: store <vscale x 16 x i1> [[M:%.*]], ptr [[M_ADDR]], align 1 87e9f53e40SFangrui Song // CHECK-NEXT: store <vscale x 16 x i16> [[VEC:%.*]], ptr [[VEC_ADDR]], align 2 88e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load <vscale x 16 x i1>, ptr [[M_ADDR]], align 1 89e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr @global_bool4, align 8 90*f28e5227SPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i8> @llvm.vector.insert.nxv2i8.v8i8(<vscale x 2 x i8> poison, <8 x i8> [[TMP1]], i64 0) 91e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = bitcast <vscale x 2 x i8> [[CAST_SCALABLE]] to <vscale x 16 x i1> 92e9f53e40SFangrui Song // CHECK-NEXT: [[TMP3:%.*]] = call <vscale x 16 x i1> @llvm.riscv.vmand.nxv16i1.i64(<vscale x 16 x i1> [[TMP0]], <vscale x 16 x i1> [[TMP2]], i64 64) 93e9f53e40SFangrui Song // CHECK-NEXT: store <vscale x 16 x i1> [[TMP3]], ptr [[MASK]], align 1 94e9f53e40SFangrui Song // CHECK-NEXT: [[TMP4:%.*]] = load <vscale x 16 x i1>, ptr [[MASK]], align 1 95e9f53e40SFangrui Song // CHECK-NEXT: [[TMP5:%.*]] = load <vscale x 16 x i16>, ptr [[VEC_ADDR]], align 2 96e9f53e40SFangrui Song // CHECK-NEXT: [[TMP6:%.*]] = load <64 x i16>, ptr @global_vec_int16m4, align 8 97*f28e5227SPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE1:%.*]] = call <vscale x 16 x i16> @llvm.vector.insert.nxv16i16.v64i16(<vscale x 16 x i16> poison, <64 x i16> [[TMP6]], i64 0) 98e9f53e40SFangrui Song // CHECK-NEXT: [[TMP7:%.*]] = call <vscale x 16 x i16> @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i64(<vscale x 16 x i16> poison, <vscale x 16 x i16> [[TMP5]], <vscale x 16 x i16> [[CAST_SCALABLE1]], <vscale x 16 x i1> [[TMP4]], i64 64, i64 3) 99e9f53e40SFangrui Song // CHECK-NEXT: [[CAST_FIXED:%.*]] = call <64 x i16> @llvm.vector.extract.v64i16.nxv16i16(<vscale x 16 x i16> [[TMP7]], i64 0) 100e9f53e40SFangrui Song // CHECK-NEXT: store <64 x i16> [[CAST_FIXED]], ptr [[RETVAL]], align 8 101e9f53e40SFangrui Song // CHECK-NEXT: [[TMP8:%.*]] = load <64 x i16>, ptr [[RETVAL]], align 8 10298e747baSPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE2:%.*]] = call <vscale x 16 x i16> @llvm.vector.insert.nxv16i16.v64i16(<vscale x 16 x i16> poison, <64 x i16> [[TMP8]], i64 0) 103e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 16 x i16> [[CAST_SCALABLE2]] 104e9f53e40SFangrui Song // 105e9f53e40SFangrui Song fixed_int16m4_t test_bool4(vbool4_t m, vint16m4_t vec) { 106e9f53e40SFangrui Song vbool4_t mask = __riscv_vmand(m, global_bool4, __riscv_v_fixed_vlen/4); 107e9f53e40SFangrui Song return __riscv_vadd(mask, vec, global_vec_int16m4, __riscv_v_fixed_vlen/4); 108e9f53e40SFangrui Song } 109e9f53e40SFangrui Song 110e9f53e40SFangrui Song // CHECK-LABEL: @test_bool32( 111e9f53e40SFangrui Song // CHECK-NEXT: entry: 112e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <8 x i32>, align 8 113e9f53e40SFangrui Song // CHECK-NEXT: [[M_ADDR:%.*]] = alloca <vscale x 2 x i1>, align 1 114e9f53e40SFangrui Song // CHECK-NEXT: [[VEC_ADDR:%.*]] = alloca <vscale x 2 x i32>, align 4 115e9f53e40SFangrui Song // CHECK-NEXT: [[MASK:%.*]] = alloca <vscale x 2 x i1>, align 1 116e9f53e40SFangrui Song // CHECK-NEXT: [[SAVED_VALUE:%.*]] = alloca <1 x i8>, align 1 117e9f53e40SFangrui Song // CHECK-NEXT: store <vscale x 2 x i1> [[M:%.*]], ptr [[M_ADDR]], align 1 118e9f53e40SFangrui Song // CHECK-NEXT: store <vscale x 2 x i32> [[VEC:%.*]], ptr [[VEC_ADDR]], align 4 119e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load <vscale x 2 x i1>, ptr [[M_ADDR]], align 1 120e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <1 x i8>, ptr @global_bool32, align 1 121e9f53e40SFangrui Song // CHECK-NEXT: store <1 x i8> [[TMP1]], ptr [[SAVED_VALUE]], align 1 122e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = load <vscale x 2 x i1>, ptr [[SAVED_VALUE]], align 1 123e9f53e40SFangrui Song // CHECK-NEXT: [[TMP3:%.*]] = call <vscale x 2 x i1> @llvm.riscv.vmand.nxv2i1.i64(<vscale x 2 x i1> [[TMP0]], <vscale x 2 x i1> [[TMP2]], i64 8) 124e9f53e40SFangrui Song // CHECK-NEXT: store <vscale x 2 x i1> [[TMP3]], ptr [[MASK]], align 1 125e9f53e40SFangrui Song // CHECK-NEXT: [[TMP4:%.*]] = load <vscale x 2 x i1>, ptr [[MASK]], align 1 126e9f53e40SFangrui Song // CHECK-NEXT: [[TMP5:%.*]] = load <vscale x 2 x i32>, ptr [[VEC_ADDR]], align 4 127e9f53e40SFangrui Song // CHECK-NEXT: [[TMP6:%.*]] = load <8 x i32>, ptr @global_vec, align 8 128*f28e5227SPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[TMP6]], i64 0) 129e9f53e40SFangrui Song // CHECK-NEXT: [[TMP7:%.*]] = call <vscale x 2 x i32> @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i64(<vscale x 2 x i32> poison, <vscale x 2 x i32> [[TMP5]], <vscale x 2 x i32> [[CAST_SCALABLE]], <vscale x 2 x i1> [[TMP4]], i64 8, i64 3) 130e9f53e40SFangrui Song // CHECK-NEXT: [[CAST_FIXED:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[TMP7]], i64 0) 131e9f53e40SFangrui Song // CHECK-NEXT: store <8 x i32> [[CAST_FIXED]], ptr [[RETVAL]], align 8 132e9f53e40SFangrui Song // CHECK-NEXT: [[TMP8:%.*]] = load <8 x i32>, ptr [[RETVAL]], align 8 13398e747baSPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE1:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[TMP8]], i64 0) 134e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 2 x i32> [[CAST_SCALABLE1]] 135e9f53e40SFangrui Song // 136e9f53e40SFangrui Song fixed_int32m1_t test_bool32(vbool32_t m, vint32m1_t vec) { 137e9f53e40SFangrui Song vbool32_t mask = __riscv_vmand(m, global_bool32, __riscv_v_fixed_vlen/32); 138e9f53e40SFangrui Song return __riscv_vadd(mask, vec, global_vec, __riscv_v_fixed_vlen/32); 139e9f53e40SFangrui Song } 140e9f53e40SFangrui Song 141e9f53e40SFangrui Song // CHECK-LABEL: @test_ptr_to_global( 142e9f53e40SFangrui Song // CHECK-NEXT: entry: 143e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <8 x i32>, align 8 144e9f53e40SFangrui Song // CHECK-NEXT: [[GLOBAL_VEC_PTR:%.*]] = alloca ptr, align 8 145e9f53e40SFangrui Song // CHECK-NEXT: store ptr @global_vec, ptr [[GLOBAL_VEC_PTR]], align 8 146e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[GLOBAL_VEC_PTR]], align 8 147e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <8 x i32>, ptr [[TMP0]], align 8 148e9f53e40SFangrui Song // CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[RETVAL]], align 8 149e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = load <8 x i32>, ptr [[RETVAL]], align 8 15098e747baSPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[TMP2]], i64 0) 151e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 2 x i32> [[CAST_SCALABLE]] 152e9f53e40SFangrui Song // 153e9f53e40SFangrui Song fixed_int32m1_t test_ptr_to_global() { 154e9f53e40SFangrui Song fixed_int32m1_t *global_vec_ptr; 155e9f53e40SFangrui Song global_vec_ptr = &global_vec; 156e9f53e40SFangrui Song return *global_vec_ptr; 157e9f53e40SFangrui Song } 158e9f53e40SFangrui Song 159e9f53e40SFangrui Song // 160e9f53e40SFangrui Song // Test casting pointer from fixed-length array to scalable vector. 161e9f53e40SFangrui Song // CHECK-LABEL: @array_arg( 162e9f53e40SFangrui Song // CHECK-NEXT: entry: 163e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <8 x i32>, align 8 164e9f53e40SFangrui Song // CHECK-NEXT: [[ARR_ADDR:%.*]] = alloca ptr, align 8 165e9f53e40SFangrui Song // CHECK-NEXT: store ptr [[ARR:%.*]], ptr [[ARR_ADDR]], align 8 166e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARR_ADDR]], align 8 167e9f53e40SFangrui Song // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds <8 x i32>, ptr [[TMP0]], i64 0 168e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <8 x i32>, ptr [[ARRAYIDX]], align 8 169e9f53e40SFangrui Song // CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[RETVAL]], align 8 170e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = load <8 x i32>, ptr [[RETVAL]], align 8 17198e747baSPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[TMP2]], i64 0) 172e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 2 x i32> [[CAST_SCALABLE]] 173e9f53e40SFangrui Song // 174e9f53e40SFangrui Song fixed_int32m1_t array_arg(fixed_int32m1_t arr[]) { 175e9f53e40SFangrui Song return arr[0]; 176e9f53e40SFangrui Song } 177e9f53e40SFangrui Song 178e9f53e40SFangrui Song // CHECK-LABEL: @address_of_array_idx_bool1( 179e9f53e40SFangrui Song // CHECK-NEXT: entry: 180e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <32 x i8>, align 8 181e9f53e40SFangrui Song // CHECK-NEXT: [[ARR:%.*]] = alloca [3 x <32 x i8>], align 8 182e9f53e40SFangrui Song // CHECK-NEXT: [[PARR:%.*]] = alloca ptr, align 8 183e9f53e40SFangrui Song // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [3 x <32 x i8>], ptr [[ARR]], i64 0, i64 0 184e9f53e40SFangrui Song // CHECK-NEXT: store ptr [[ARRAYIDX]], ptr [[PARR]], align 8 185e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PARR]], align 8 186e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <32 x i8>, ptr [[TMP0]], align 8 187e9f53e40SFangrui Song // CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[RETVAL]], align 8 188e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = load <32 x i8>, ptr [[RETVAL]], align 8 18998e747baSPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v32i8(<vscale x 8 x i8> poison, <32 x i8> [[TMP2]], i64 0) 190e9f53e40SFangrui Song // CHECK-NEXT: [[TMP3:%.*]] = bitcast <vscale x 8 x i8> [[CAST_SCALABLE]] to <vscale x 64 x i1> 191e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 64 x i1> [[TMP3]] 192e9f53e40SFangrui Song // 193e9f53e40SFangrui Song fixed_bool1_t address_of_array_idx_bool1() { 194e9f53e40SFangrui Song fixed_bool1_t arr[3]; 195e9f53e40SFangrui Song fixed_bool1_t *parr; 196e9f53e40SFangrui Song parr = &arr[0]; 197e9f53e40SFangrui Song return *parr; 198e9f53e40SFangrui Song } 199e9f53e40SFangrui Song 200e9f53e40SFangrui Song // CHECK-LABEL: @address_of_array_idx_bool4( 201e9f53e40SFangrui Song // CHECK-NEXT: entry: 202e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <8 x i8>, align 8 203e9f53e40SFangrui Song // CHECK-NEXT: [[ARR:%.*]] = alloca [3 x <8 x i8>], align 8 204e9f53e40SFangrui Song // CHECK-NEXT: [[PARR:%.*]] = alloca ptr, align 8 205e9f53e40SFangrui Song // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [3 x <8 x i8>], ptr [[ARR]], i64 0, i64 0 206e9f53e40SFangrui Song // CHECK-NEXT: store ptr [[ARRAYIDX]], ptr [[PARR]], align 8 207e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PARR]], align 8 208e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[TMP0]], align 8 209e9f53e40SFangrui Song // CHECK-NEXT: store <8 x i8> [[TMP1]], ptr [[RETVAL]], align 8 210e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = load <8 x i8>, ptr [[RETVAL]], align 8 21198e747baSPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i8> @llvm.vector.insert.nxv2i8.v8i8(<vscale x 2 x i8> poison, <8 x i8> [[TMP2]], i64 0) 212e9f53e40SFangrui Song // CHECK-NEXT: [[TMP3:%.*]] = bitcast <vscale x 2 x i8> [[CAST_SCALABLE]] to <vscale x 16 x i1> 213e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 16 x i1> [[TMP3]] 214e9f53e40SFangrui Song // 215e9f53e40SFangrui Song fixed_bool4_t address_of_array_idx_bool4() { 216e9f53e40SFangrui Song fixed_bool4_t arr[3]; 217e9f53e40SFangrui Song fixed_bool4_t *parr; 218e9f53e40SFangrui Song parr = &arr[0]; 219e9f53e40SFangrui Song return *parr; 220e9f53e40SFangrui Song } 221e9f53e40SFangrui Song 222e9f53e40SFangrui Song // CHECK-LABEL: @address_of_array_idx_bool32( 223e9f53e40SFangrui Song // CHECK-NEXT: entry: 224e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <1 x i8>, align 1 225e9f53e40SFangrui Song // CHECK-NEXT: [[ARR:%.*]] = alloca [3 x <1 x i8>], align 1 226e9f53e40SFangrui Song // CHECK-NEXT: [[PARR:%.*]] = alloca ptr, align 8 227e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL_COERCE:%.*]] = alloca <vscale x 2 x i1>, align 1 228e9f53e40SFangrui Song // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [3 x <1 x i8>], ptr [[ARR]], i64 0, i64 0 229e9f53e40SFangrui Song // CHECK-NEXT: store ptr [[ARRAYIDX]], ptr [[PARR]], align 8 230e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PARR]], align 8 231e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <1 x i8>, ptr [[TMP0]], align 1 232e9f53e40SFangrui Song // CHECK-NEXT: store <1 x i8> [[TMP1]], ptr [[RETVAL]], align 1 233e9f53e40SFangrui Song // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[RETVAL_COERCE]], ptr align 1 [[RETVAL]], i64 1, i1 false) 234e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = load <vscale x 2 x i1>, ptr [[RETVAL_COERCE]], align 1 235e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 2 x i1> [[TMP2]] 236e9f53e40SFangrui Song // 237e9f53e40SFangrui Song fixed_bool32_t address_of_array_idx_bool32() { 238e9f53e40SFangrui Song fixed_bool32_t arr[3]; 239e9f53e40SFangrui Song fixed_bool32_t *parr; 240e9f53e40SFangrui Song parr = &arr[0]; 241e9f53e40SFangrui Song return *parr; 242e9f53e40SFangrui Song } 243e9f53e40SFangrui Song 244e9f53e40SFangrui Song // CHECK-LABEL: @test_cast( 245e9f53e40SFangrui Song // CHECK-NEXT: entry: 246e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <8 x i32>, align 8 247e9f53e40SFangrui Song // CHECK-NEXT: [[VEC_ADDR:%.*]] = alloca <vscale x 2 x i32>, align 4 248e9f53e40SFangrui Song // CHECK-NEXT: store <vscale x 2 x i32> [[VEC:%.*]], ptr [[VEC_ADDR]], align 4 249e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load <8 x i32>, ptr @global_vec, align 8 250*f28e5227SPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[TMP0]], i64 0) 251e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <vscale x 2 x i32>, ptr [[VEC_ADDR]], align 4 252e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32.i64(<vscale x 2 x i32> poison, <vscale x 2 x i32> [[CAST_SCALABLE]], <vscale x 2 x i32> [[TMP1]], i64 8) 253e9f53e40SFangrui Song // CHECK-NEXT: [[CAST_FIXED:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[TMP2]], i64 0) 254e9f53e40SFangrui Song // CHECK-NEXT: store <8 x i32> [[CAST_FIXED]], ptr [[RETVAL]], align 8 255e9f53e40SFangrui Song // CHECK-NEXT: [[TMP3:%.*]] = load <8 x i32>, ptr [[RETVAL]], align 8 25698e747baSPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE1:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[TMP3]], i64 0) 257e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 2 x i32> [[CAST_SCALABLE1]] 258e9f53e40SFangrui Song // 259e9f53e40SFangrui Song fixed_int32m1_t test_cast(vint32m1_t vec) { 260e9f53e40SFangrui Song return __riscv_vadd(global_vec, vec, __riscv_v_fixed_vlen/32); 261e9f53e40SFangrui Song } 262e9f53e40SFangrui Song 263e9f53e40SFangrui Song // CHECK-LABEL: @test_ptr_to_global_m2( 264e9f53e40SFangrui Song // CHECK-NEXT: entry: 265e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <16 x i32>, align 8 266e9f53e40SFangrui Song // CHECK-NEXT: [[GLOBAL_VEC_PTR:%.*]] = alloca ptr, align 8 267e9f53e40SFangrui Song // CHECK-NEXT: store ptr @global_vec_m2, ptr [[GLOBAL_VEC_PTR]], align 8 268e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[GLOBAL_VEC_PTR]], align 8 269e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <16 x i32>, ptr [[TMP0]], align 8 270e9f53e40SFangrui Song // CHECK-NEXT: store <16 x i32> [[TMP1]], ptr [[RETVAL]], align 8 271e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = load <16 x i32>, ptr [[RETVAL]], align 8 27298e747baSPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> poison, <16 x i32> [[TMP2]], i64 0) 273e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 4 x i32> [[CAST_SCALABLE]] 274e9f53e40SFangrui Song // 275e9f53e40SFangrui Song fixed_int32m2_t test_ptr_to_global_m2() { 276e9f53e40SFangrui Song fixed_int32m2_t *global_vec_ptr; 277e9f53e40SFangrui Song global_vec_ptr = &global_vec_m2; 278e9f53e40SFangrui Song return *global_vec_ptr; 279e9f53e40SFangrui Song } 280e9f53e40SFangrui Song 281e9f53e40SFangrui Song // 282e9f53e40SFangrui Song // Test casting pointer from fixed-length array to scalable vector. 283e9f53e40SFangrui Song // CHECK-LABEL: @array_arg_m2( 284e9f53e40SFangrui Song // CHECK-NEXT: entry: 285e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <16 x i32>, align 8 286e9f53e40SFangrui Song // CHECK-NEXT: [[ARR_ADDR:%.*]] = alloca ptr, align 8 287e9f53e40SFangrui Song // CHECK-NEXT: store ptr [[ARR:%.*]], ptr [[ARR_ADDR]], align 8 288e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARR_ADDR]], align 8 289e9f53e40SFangrui Song // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds <16 x i32>, ptr [[TMP0]], i64 0 290e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <16 x i32>, ptr [[ARRAYIDX]], align 8 291e9f53e40SFangrui Song // CHECK-NEXT: store <16 x i32> [[TMP1]], ptr [[RETVAL]], align 8 292e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = load <16 x i32>, ptr [[RETVAL]], align 8 29398e747baSPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> poison, <16 x i32> [[TMP2]], i64 0) 294e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 4 x i32> [[CAST_SCALABLE]] 295e9f53e40SFangrui Song // 296e9f53e40SFangrui Song fixed_int32m2_t array_arg_m2(fixed_int32m2_t arr[]) { 297e9f53e40SFangrui Song return arr[0]; 298e9f53e40SFangrui Song } 299e9f53e40SFangrui Song 300e9f53e40SFangrui Song // CHECK-LABEL: @test_cast_m2( 301e9f53e40SFangrui Song // CHECK-NEXT: entry: 302e9f53e40SFangrui Song // CHECK-NEXT: [[RETVAL:%.*]] = alloca <16 x i32>, align 8 303e9f53e40SFangrui Song // CHECK-NEXT: [[VEC_ADDR:%.*]] = alloca <vscale x 4 x i32>, align 4 304e9f53e40SFangrui Song // CHECK-NEXT: store <vscale x 4 x i32> [[VEC:%.*]], ptr [[VEC_ADDR]], align 4 305e9f53e40SFangrui Song // CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr @global_vec_m2, align 8 306*f28e5227SPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> poison, <16 x i32> [[TMP0]], i64 0) 307e9f53e40SFangrui Song // CHECK-NEXT: [[TMP1:%.*]] = load <vscale x 4 x i32>, ptr [[VEC_ADDR]], align 4 308e9f53e40SFangrui Song // CHECK-NEXT: [[TMP2:%.*]] = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32.i64(<vscale x 4 x i32> poison, <vscale x 4 x i32> [[CAST_SCALABLE]], <vscale x 4 x i32> [[TMP1]], i64 16) 309e9f53e40SFangrui Song // CHECK-NEXT: [[CAST_FIXED:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[TMP2]], i64 0) 310e9f53e40SFangrui Song // CHECK-NEXT: store <16 x i32> [[CAST_FIXED]], ptr [[RETVAL]], align 8 311e9f53e40SFangrui Song // CHECK-NEXT: [[TMP3:%.*]] = load <16 x i32>, ptr [[RETVAL]], align 8 31298e747baSPedro Lobo // CHECK-NEXT: [[CAST_SCALABLE1:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> poison, <16 x i32> [[TMP3]], i64 0) 313e9f53e40SFangrui Song // CHECK-NEXT: ret <vscale x 4 x i32> [[CAST_SCALABLE1]] 314e9f53e40SFangrui Song // 315e9f53e40SFangrui Song fixed_int32m2_t test_cast_m2(vint32m2_t vec) { 316e9f53e40SFangrui Song return __riscv_vadd(global_vec_m2, vec, __riscv_v_fixed_vlen/16); 317e9f53e40SFangrui Song } 318