1; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s 2; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} 3 4; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s 5; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} 6 7; CHECK-DAG: OpName [[TRUNC32_16:%.*]] "i32toi16" 8; CHECK-DAG: OpName [[TRUNC32_8:%.*]] "i32toi8" 9; CHECK-DAG: OpName [[TRUNC16_8:%.*]] "i16toi8" 10; CHECK-DAG: OpName [[SEXT8_32:%.*]] "s8tos32" 11; CHECK-DAG: OpName [[SEXT8_16:%.*]] "s8tos16" 12; CHECK-DAG: OpName [[SEXT16_32:%.*]] "s16tos32" 13; CHECK-DAG: OpName [[ZEXT8_32:%.*]] "u8tou32" 14; CHECK-DAG: OpName [[ZEXT8_16:%.*]] "u8tou16" 15; CHECK-DAG: OpName [[ZEXT16_32:%.*]] "u16tou32" 16 17; CHECK-DAG: OpName %[[#R17:]] "r17" 18; CHECK-DAG: OpName %[[#R18:]] "r18" 19; CHECK-DAG: OpName %[[#R19:]] "r19" 20; CHECK-DAG: OpName %[[#R20:]] "r20" 21; CHECK-DAG: OpName %[[#R21:]] "r21" 22 23; CHECK-DAG: OpName [[TRUNC32_16v4:%.*]] "i32toi16v4" 24; CHECK-DAG: OpName [[TRUNC32_8v4:%.*]] "i32toi8v4" 25; CHECK-DAG: OpName [[TRUNC16_8v4:%.*]] "i16toi8v4" 26; CHECK-DAG: OpName [[SEXT8_32v4:%.*]] "s8tos32v4" 27; CHECK-DAG: OpName [[SEXT8_16v4:%.*]] "s8tos16v4" 28; CHECK-DAG: OpName [[SEXT16_32v4:%.*]] "s16tos32v4" 29; CHECK-DAG: OpName [[ZEXT8_32v4:%.*]] "u8tou32v4" 30; CHECK-DAG: OpName [[ZEXT8_16v4:%.*]] "u8tou16v4" 31; CHECK-DAG: OpName [[ZEXT16_32v4:%.*]] "u16tou32v4" 32 33; CHECK-DAG: OpDecorate %[[#R17]] FPRoundingMode RTZ 34; CHECK-DAG: OpDecorate %[[#R18]] FPRoundingMode RTE 35; CHECK-DAG: OpDecorate %[[#R19]] FPRoundingMode RTP 36; CHECK-DAG: OpDecorate %[[#R20]] FPRoundingMode RTN 37; CHECK-DAG: OpDecorate %[[#R21]] SaturatedConversion 38 39; CHECK-DAG: [[F32:%.*]] = OpTypeFloat 32 40; CHECK-DAG: [[F16:%.*]] = OpTypeFloat 16 41; CHECK-DAG: [[U64:%.*]] = OpTypeInt 64 0 42; CHECK-DAG: [[U32:%.*]] = OpTypeInt 32 0 43; CHECK-DAG: [[U16:%.*]] = OpTypeInt 16 0 44; CHECK-DAG: [[U8:%.*]] = OpTypeInt 8 0 45; CHECK-DAG: [[F32v2:%.*]] = OpTypeVector [[F32]] 2 46; CHECK-DAG: [[U32v4:%.*]] = OpTypeVector [[U32]] 4 47; CHECK-DAG: [[U16v4:%.*]] = OpTypeVector [[U16]] 4 48; CHECK-DAG: [[U8v4:%.*]] = OpTypeVector [[U8]] 4 49 50 51; CHECK: [[TRUNC32_16]] = OpFunction [[U16]] 52; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U32]] 53; CHECK: OpLabel 54; CHECK: [[R:%.*]] = OpUConvert [[U16]] [[A]] 55; CHECK: OpReturnValue [[R]] 56; CHECK-NEXT: OpFunctionEnd 57define i16 @i32toi16(i32 %a) { 58 %r = trunc i32 %a to i16 59 ret i16 %r 60} 61 62; CHECK: [[TRUNC32_8]] = OpFunction [[U8]] 63; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U32]] 64; CHECK: OpLabel 65; CHECK: [[R:%.*]] = OpUConvert [[U8]] [[A]] 66; CHECK: OpReturnValue [[R]] 67; CHECK-NEXT: OpFunctionEnd 68define i8 @i32toi8(i32 %a) { 69 %r = trunc i32 %a to i8 70 ret i8 %r 71} 72 73; CHECK: [[TRUNC16_8]] = OpFunction [[U8]] 74; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U16]] 75; CHECK: OpLabel 76; CHECK: [[R:%.*]] = OpUConvert [[U8]] [[A]] 77; CHECK: OpReturnValue [[R]] 78; CHECK-NEXT: OpFunctionEnd 79define i8 @i16toi8(i16 %a) { 80 %r = trunc i16 %a to i8 81 ret i8 %r 82} 83 84 85; CHECK: [[SEXT8_32]] = OpFunction [[U32]] 86; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U8]] 87; CHECK: OpLabel 88; CHECK: [[R:%.*]] = OpSConvert [[U32]] [[A]] 89; CHECK: OpReturnValue [[R]] 90; CHECK-NEXT: OpFunctionEnd 91define i32 @s8tos32(i8 %a) { 92 %r = sext i8 %a to i32 93 ret i32 %r 94} 95 96; CHECK: [[SEXT8_16]] = OpFunction [[U16]] 97; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U8]] 98; CHECK: OpLabel 99; CHECK: [[R:%.*]] = OpSConvert [[U16]] [[A]] 100; CHECK: OpReturnValue [[R]] 101; CHECK-NEXT: OpFunctionEnd 102define i16 @s8tos16(i8 %a) { 103 %r = sext i8 %a to i16 104 ret i16 %r 105} 106 107; CHECK: [[SEXT16_32]] = OpFunction [[U32]] 108; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U16]] 109; CHECK: OpLabel 110; CHECK: [[R:%.*]] = OpSConvert [[U32]] [[A]] 111; CHECK: OpReturnValue [[R]] 112; CHECK-NEXT: OpFunctionEnd 113define i32 @s16tos32(i16 %a) { 114 %r = sext i16 %a to i32 115 ret i32 %r 116} 117 118; CHECK: [[ZEXT8_32]] = OpFunction [[U32]] 119; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U8]] 120; CHECK: OpLabel 121; CHECK: [[R:%.*]] = OpUConvert [[U32]] [[A]] 122; CHECK: OpReturnValue [[R]] 123; CHECK-NEXT: OpFunctionEnd 124define i32 @u8tou32(i8 %a) { 125 %r = zext i8 %a to i32 126 ret i32 %r 127} 128 129; CHECK: [[ZEXT8_16]] = OpFunction [[U16]] 130; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U8]] 131; CHECK: OpLabel 132; CHECK: [[R:%.*]] = OpUConvert [[U16]] [[A]] 133; CHECK: OpReturnValue [[R]] 134; CHECK-NEXT: OpFunctionEnd 135define i16 @u8tou16(i8 %a) { 136 %r = zext i8 %a to i16 137 ret i16 %r 138} 139 140; CHECK: [[ZEXT16_32]] = OpFunction [[U32]] 141; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U16]] 142; CHECK: OpLabel 143; CHECK: [[R:%.*]] = OpUConvert [[U32]] [[A]] 144; CHECK: OpReturnValue [[R]] 145; CHECK-NEXT: OpFunctionEnd 146define i32 @u16tou32(i16 %a) { 147 %r = zext i16 %a to i32 148 ret i32 %r 149} 150 151; CHECK: [[TRUNC32_16v4]] = OpFunction [[U16v4]] 152; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U32v4]] 153; CHECK: OpLabel 154; CHECK: [[R:%.*]] = OpUConvert [[U16v4]] [[A]] 155; CHECK: OpReturnValue [[R]] 156; CHECK-NEXT: OpFunctionEnd 157define <4 x i16> @i32toi16v4(<4 x i32> %a) { 158 %r = trunc <4 x i32> %a to <4 x i16> 159 ret <4 x i16> %r 160} 161 162; CHECK: [[TRUNC32_8v4]] = OpFunction [[U8v4]] 163; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U32v4]] 164; CHECK: OpLabel 165; CHECK: [[R:%.*]] = OpUConvert [[U8v4]] [[A]] 166; CHECK: OpReturnValue [[R]] 167; CHECK-NEXT: OpFunctionEnd 168define <4 x i8> @i32toi8v4(<4 x i32> %a) { 169 %r = trunc <4 x i32> %a to <4 x i8> 170 ret <4 x i8> %r 171} 172 173; CHECK: [[TRUNC16_8v4]] = OpFunction [[U8v4]] 174; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U16v4]] 175; CHECK: OpLabel 176; CHECK: [[R:%.*]] = OpUConvert [[U8v4]] [[A]] 177; CHECK: OpReturnValue [[R]] 178; CHECK-NEXT: OpFunctionEnd 179define <4 x i8> @i16toi8v4(<4 x i16> %a) { 180 %r = trunc <4 x i16> %a to <4 x i8> 181 ret <4 x i8> %r 182} 183 184 185; CHECK: [[SEXT8_32v4]] = OpFunction [[U32v4]] 186; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U8v4]] 187; CHECK: OpLabel 188; CHECK: [[R:%.*]] = OpSConvert [[U32v4]] [[A]] 189; CHECK: OpReturnValue [[R]] 190; CHECK-NEXT: OpFunctionEnd 191define <4 x i32> @s8tos32v4(<4 x i8> %a) { 192 %r = sext <4 x i8> %a to <4 x i32> 193 ret <4 x i32> %r 194} 195 196; CHECK: [[SEXT8_16v4]] = OpFunction [[U16v4]] 197; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U8v4]] 198; CHECK: OpLabel 199; CHECK: [[R:%.*]] = OpSConvert [[U16v4]] [[A]] 200; CHECK: OpReturnValue [[R]] 201; CHECK-NEXT: OpFunctionEnd 202define <4 x i16> @s8tos16v4(<4 x i8> %a) { 203 %r = sext <4 x i8> %a to <4 x i16> 204 ret <4 x i16> %r 205} 206 207; CHECK: [[SEXT16_32v4]] = OpFunction [[U32v4]] 208; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U16v4]] 209; CHECK: OpLabel 210; CHECK: [[R:%.*]] = OpSConvert [[U32v4]] [[A]] 211; CHECK: OpReturnValue [[R]] 212; CHECK-NEXT: OpFunctionEnd 213define <4 x i32> @s16tos32v4(<4 x i16> %a) { 214 %r = sext <4 x i16> %a to <4 x i32> 215 ret <4 x i32> %r 216} 217 218; CHECK: [[ZEXT8_32v4]] = OpFunction [[U32v4]] 219; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U8v4]] 220; CHECK: OpLabel 221; CHECK: [[R:%.*]] = OpUConvert [[U32v4]] [[A]] 222; CHECK: OpReturnValue [[R]] 223; CHECK-NEXT: OpFunctionEnd 224define <4 x i32> @u8tou32v4(<4 x i8> %a) { 225 %r = zext <4 x i8> %a to <4 x i32> 226 ret <4 x i32> %r 227} 228 229; CHECK: [[ZEXT8_16v4]] = OpFunction [[U16v4]] 230; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U8v4]] 231; CHECK: OpLabel 232; CHECK: [[R:%.*]] = OpUConvert [[U16v4]] [[A]] 233; CHECK: OpReturnValue [[R]] 234; CHECK-NEXT: OpFunctionEnd 235define <4 x i16> @u8tou16v4(<4 x i8> %a) { 236 %r = zext <4 x i8> %a to <4 x i16> 237 ret <4 x i16> %r 238} 239 240; CHECK: [[ZEXT16_32v4]] = OpFunction [[U32v4]] 241; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[U16v4]] 242; CHECK: OpLabel 243; CHECK: [[R:%.*]] = OpUConvert [[U32v4]] [[A]] 244; CHECK: OpReturnValue [[R]] 245; CHECK-NEXT: OpFunctionEnd 246define <4 x i32> @u16tou32v4(<4 x i16> %a) { 247 %r = zext <4 x i16> %a to <4 x i32> 248 ret <4 x i32> %r 249} 250 251; CHECK: OpFunction 252; CHECK: [[Arg1:%.*]] = OpFunctionParameter 253; CHECK: [[Arg2:%.*]] = OpFunctionParameter 254; CHECK: %[[#]] = OpConvertFToU [[U32]] %[[#]] 255; CHECK: %[[#]] = OpConvertFToS [[U32]] %[[#]] 256; CHECK: %[[#]] = OpConvertSToF [[F32]] %[[#]] 257; CHECK: %[[#]] = OpConvertUToF [[F32]] %[[#]] 258; CHECK: %[[#]] = OpUConvert [[U32]] %[[#]] 259; CHECK: %[[#]] = OpSConvert [[U32]] %[[#]] 260; CHECK: %[[#]] = OpFConvert [[F16]] %[[#]] 261; CHECK: %[[#]] = OpQuantizeToF16 [[F32]] %[[#]] 262; CHECK: %[[#]] = OpSatConvertSToU [[U64]] %[[#]] 263; CHECK: %[[#]] = OpSatConvertUToS [[U64]] %[[#]] 264; CHECK: %[[#]] = OpConvertPtrToU [[U64]] [[Arg1]] 265; CHECK: %[[#]] = OpConvertUToPtr %[[#]] [[Arg2]] 266; CHECK: %[[#]] = OpUConvert [[U32v4]] %[[#]] 267; CHECK: %[[#]] = OpSConvert [[U32v4]] %[[#]] 268; CHECK: %[[#]] = OpConvertUToF [[F32]] %[[#]] 269; CHECK: %[[#]] = OpConvertUToF [[F32]] %[[#]] 270; CHECK: %[[#R17]] = OpFConvert [[F32v2]] %[[#]] 271; CHECK: %[[#R18]] = OpFConvert [[F32v2]] %[[#]] 272; CHECK: %[[#R19]] = OpFConvert [[F32v2]] %[[#]] 273; CHECK: %[[#R20]] = OpFConvert [[F32v2]] %[[#]] 274; CHECK: %[[#R21]] = OpConvertFToU [[U8]] %[[#]] 275; CHECK: OpFunctionEnd 276define dso_local spir_kernel void @test_wrappers(ptr addrspace(4) %arg, i64 %arg_ptr, <4 x i8> %arg_v2) { 277 %r1 = call spir_func i32 @__spirv_ConvertFToU(float 0.000000e+00) 278 %r2 = call spir_func i32 @__spirv_ConvertFToS(float 0.000000e+00) 279 %r3 = call spir_func float @__spirv_ConvertSToF(i32 1) 280 %r4 = call spir_func float @__spirv_ConvertUToF(i32 1) 281 %r5 = call spir_func i32 @__spirv_UConvert(i64 1) 282 %r6 = call spir_func i32 @__spirv_SConvert(i64 1) 283 %r7 = call spir_func half @__spirv_FConvert(float 0.000000e+00) 284 %r8 = call spir_func float @__spirv_QuantizeToF16(float 0.000000e+00) 285 %r9 = call spir_func i64 @__spirv_SatConvertSToU(i64 1) 286 %r10 = call spir_func i64 @__spirv_SatConvertUToS(i64 1) 287 %r11 = call spir_func i64 @__spirv_ConvertPtrToU(ptr addrspace(4) %arg) 288 %r12 = call spir_func ptr addrspace(4) @__spirv_ConvertUToPtr(i64 %arg_ptr) 289 %r13 = call spir_func <4 x i32> @_Z22__spirv_UConvert_Rint2Dv2_a(<4 x i8> %arg_v2) 290 %r14 = call spir_func <4 x i32> @_Z22__spirv_SConvert_Rint2Dv2_a(<4 x i8> %arg_v2) 291 %r15 = call spir_func float @_Z30__spirv_ConvertUToF_Rfloat_rtz(i64 %arg_ptr) 292 %r16 = call spir_func float @__spirv_ConvertUToF_Rfloat_rtz(i64 %arg_ptr) 293 %r17 = call spir_func <2 x float> @_Z28__spirv_FConvert_Rfloat2_rtzDv2_DF16_(<2 x half> noundef <half 0xH409A, half 0xH439A>) 294 %r18 = call spir_func <2 x float> @_Z28__spirv_FConvert_Rfloat2_rteDv2_DF16_(<2 x half> noundef <half 0xH409A, half 0xH439A>) 295 %r19 = call spir_func <2 x float> @_Z28__spirv_FConvert_Rfloat2_rtpDv2_DF16_(<2 x half> noundef <half 0xH409A, half 0xH439A>) 296 %r20 = call spir_func <2 x float> @_Z28__spirv_FConvert_Rfloat2_rtnDv2_DF16_(<2 x half> noundef <half 0xH409A, half 0xH439A>) 297 %r21 = call spir_func i8 @_Z30__spirv_ConvertFToU_Ruchar_satf(float noundef 42.0) 298 ret void 299} 300 301declare dso_local spir_func i32 @__spirv_ConvertFToU(float) 302declare dso_local spir_func i32 @__spirv_ConvertFToS(float) 303declare dso_local spir_func float @__spirv_ConvertSToF(i32) 304declare dso_local spir_func float @__spirv_ConvertUToF(i32) 305declare dso_local spir_func i32 @__spirv_UConvert(i64) 306declare dso_local spir_func i32 @__spirv_SConvert(i64) 307declare dso_local spir_func half @__spirv_FConvert(float) 308declare dso_local spir_func float @__spirv_QuantizeToF16(float) 309declare dso_local spir_func i64 @__spirv_SatConvertSToU(i64) 310declare dso_local spir_func i64 @__spirv_SatConvertUToS(i64) 311declare dso_local spir_func i64 @__spirv_ConvertPtrToU(ptr addrspace(4)) 312declare dso_local spir_func ptr addrspace(4) @__spirv_ConvertUToPtr(i64) 313declare dso_local spir_func <4 x i32> @_Z22__spirv_UConvert_Rint2Dv2_a(<4 x i8>) 314declare dso_local spir_func <4 x i32> @_Z22__spirv_SConvert_Rint2Dv2_a(<4 x i8>) 315declare dso_local spir_func float @_Z30__spirv_ConvertUToF_Rfloat_rtz(i64) 316declare dso_local spir_func float @__spirv_ConvertUToF_Rfloat_rtz(i64) 317declare dso_local spir_func <2 x float> @_Z28__spirv_FConvert_Rfloat2_rtzDv2_DF16_(<2 x half> noundef) 318declare dso_local spir_func <2 x float> @_Z28__spirv_FConvert_Rfloat2_rteDv2_DF16_(<2 x half> noundef) 319declare dso_local spir_func <2 x float> @_Z28__spirv_FConvert_Rfloat2_rtpDv2_DF16_(<2 x half> noundef) 320declare dso_local spir_func <2 x float> @_Z28__spirv_FConvert_Rfloat2_rtnDv2_DF16_(<2 x half> noundef) 321declare dso_local spir_func i8 @_Z30__spirv_ConvertFToU_Ruchar_satf(float) 322