406 lines · plain
1; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s2; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}3 4; CHECK: %[[#extinst_id:]] = OpExtInstImport "OpenCL.std"5 6; CHECK: %[[#var0:]] = OpTypeFloat 167; CHECK: %[[#var1:]] = OpTypeFloat 328; CHECK: %[[#var2:]] = OpTypeFloat 649; CHECK: %[[#var3:]] = OpTypeVector %[[#var1]] 410 11; CHECK: OpFunction12; CHECK: %[[#]] = OpExtInst %[[#var0]] %[[#extinst_id]] fabs13; CHECK: OpFunctionEnd14 15define spir_func half @TestFabs16(half %x) local_unnamed_addr {16entry:17 %t = tail call half @llvm.fabs.f16(half %x)18 ret half %t19}20 21; CHECK: OpFunction22; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] fabs23; CHECK: OpFunctionEnd24 25define spir_func float @TestFabs32(float %x) local_unnamed_addr {26entry:27 %t = tail call float @llvm.fabs.f32(float %x)28 ret float %t29}30 31; CHECK: OpFunction32; CHECK: %[[#]] = OpExtInst %[[#var2]] %[[#extinst_id]] fabs33; CHECK: OpFunctionEnd34 35define spir_func double @TestFabs64(double %x) local_unnamed_addr {36entry:37 %t = tail call double @llvm.fabs.f64(double %x)38 ret double %t39}40 41; CHECK: OpFunction42; CHECK: %[[#]] = OpExtInst %[[#var3]] %[[#extinst_id]] fabs43; CHECK: OpFunctionEnd44 45define spir_func <4 x float> @TestFabsVec(<4 x float> %x) local_unnamed_addr {46entry:47 %t = tail call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)48 ret <4 x float> %t49}50 51declare half @llvm.fabs.f16(half)52declare float @llvm.fabs.f32(float)53declare double @llvm.fabs.f64(double)54declare <4 x float> @llvm.fabs.v4f32(<4 x float>)55 56;; We checked several types with fabs, but the type check works the same for57;; all intrinsics being translated, so for the rest we'll just test one type.58 59; CHECK: OpFunction60; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] ceil61; CHECK: OpFunctionEnd62 63define spir_func float @TestCeil(float %x) local_unnamed_addr {64entry:65 %t = tail call float @llvm.ceil.f32(float %x)66 ret float %t67}68 69declare float @llvm.ceil.f32(float)70 71; CHECK: OpFunction72; CHECK: %[[#x:]] = OpFunctionParameter %[[#]]73; CHECK: %[[#n:]] = OpFunctionParameter %[[#]]74; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] pown %[[#x]] %[[#n]]75; CHECK: OpFunctionEnd76 77define spir_func float @TestPowi(float %x, i32 %n) local_unnamed_addr {78entry:79 %t = tail call float @llvm.powi.f32(float %x, i32 %n)80 ret float %t81}82 83declare float @llvm.powi.f32(float, i32)84 85; CHECK: OpFunction86; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] sin87; CHECK: OpFunctionEnd88 89define spir_func float @TestSin(float %x) local_unnamed_addr {90entry:91 %t = tail call float @llvm.sin.f32(float %x)92 ret float %t93}94 95declare float @llvm.sin.f32(float)96 97; CHECK: OpFunction98; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] cos99; CHECK: OpFunctionEnd100 101define spir_func float @TestCos(float %x) local_unnamed_addr {102entry:103 %t = tail call float @llvm.cos.f32(float %x)104 ret float %t105}106 107declare float @llvm.cos.f32(float)108 109; CHECK: OpFunction110; CHECK: %[[#x:]] = OpFunctionParameter %[[#]]111; CHECK: %[[#y:]] = OpFunctionParameter %[[#]]112; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] pow %[[#x]] %[[#y]]113; CHECK: OpFunctionEnd114 115define spir_func float @TestPow(float %x, float %y) local_unnamed_addr {116entry:117 %t = tail call float @llvm.pow.f32(float %x, float %y)118 ret float %t119}120 121declare float @llvm.pow.f32(float, float)122 123; CHECK: OpFunction124; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] exp125; CHECK: OpFunctionEnd126 127define spir_func float @TestExp(float %x) local_unnamed_addr {128entry:129 %t = tail call float @llvm.exp.f32(float %x)130 ret float %t131}132 133declare float @llvm.exp.f32(float)134 135; CHECK: OpFunction136; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] exp2137; CHECK: OpFunctionEnd138 139define spir_func float @TestExp2(float %x) local_unnamed_addr {140entry:141 %t = tail call float @llvm.exp2.f32(float %x)142 ret float %t143}144 145declare float @llvm.exp2.f32(float)146 147; CHECK: OpFunction148; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] log149; CHECK: OpFunctionEnd150 151define spir_func float @TestLog(float %x) local_unnamed_addr {152entry:153 %t = tail call float @llvm.log.f32(float %x)154 ret float %t155}156 157declare float @llvm.log.f32(float)158 159; CHECK: OpFunction160; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] log10161; CHECK: OpFunctionEnd162 163define spir_func float @TestLog10(float %x) local_unnamed_addr {164entry:165 %t = tail call float @llvm.log10.f32(float %x)166 ret float %t167}168 169declare float @llvm.log10.f32(float)170 171; CHECK: OpFunction172; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] log2173; CHECK: OpFunctionEnd174 175define spir_func float @TestLog2(float %x) local_unnamed_addr {176entry:177 %t = tail call float @llvm.log2.f32(float %x)178 ret float %t179}180 181declare float @llvm.log2.f32(float)182 183; CHECK: OpFunction184; CHECK: %[[#x:]] = OpFunctionParameter %[[#]]185; CHECK: %[[#y:]] = OpFunctionParameter %[[#]]186; CHECK: %[[#res:]] = OpExtInst %[[#]] %[[#]] fmin %[[#x]] %[[#y]]187; CHECK: OpReturnValue %[[#res]]188 189define spir_func float @TestMinNum(float %x, float %y) {190entry:191 %t = call float @llvm.minnum.f32(float %x, float %y)192 ret float %t193}194 195declare float @llvm.minnum.f32(float, float)196 197; CHECK: OpFunction198; CHECK: %[[#x:]] = OpFunctionParameter %[[#]]199; CHECK: %[[#y:]] = OpFunctionParameter %[[#]]200; CHECK: %[[#res:]] = OpExtInst %[[#]] %[[#]] fmax %[[#x]] %[[#y]]201; CHECK: OpReturnValue %[[#res]]202 203define spir_func float @TestMaxNum(float %x, float %y) {204entry:205 %t = call float @llvm.maxnum.f32(float %x, float %y)206 ret float %t207}208 209declare float @llvm.maxnum.f32(float, float)210 211; CHECK: OpFunction212; CHECK: %[[#x:]] = OpFunctionParameter %[[#]]213; CHECK: %[[#y:]] = OpFunctionParameter %[[#]]214; CHECK: %[[#res:]] = OpExtInst %[[#]] %[[#]] fmin %[[#x]] %[[#y]]215; CHECK: OpReturnValue %[[#res]]216 217define spir_func float @TestMinimum(float %x, float %y) {218entry:219 %t = call float @llvm.minimum.f32(float %x, float %y)220 ret float %t221}222 223declare float @llvm.minimum.f32(float, float)224 225; CHECK: OpFunction226; CHECK: %[[#x:]] = OpFunctionParameter %[[#]]227; CHECK: %[[#y:]] = OpFunctionParameter %[[#]]228; CHECK: %[[#res:]] = OpExtInst %[[#]] %[[#]] fmax %[[#x]] %[[#y]]229; CHECK: OpReturnValue %[[#res]]230 231define spir_func float @TestMaximum(float %x, float %y) {232entry:233 %t = call float @llvm.maximum.f32(float %x, float %y)234 ret float %t235}236 237declare float @llvm.maximum.f32(float, float)238 239; CHECK: OpFunction240; CHECK: %[[#x:]] = OpFunctionParameter %[[#]]241; CHECK: %[[#y:]] = OpFunctionParameter %[[#]]242; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] copysign %[[#x]] %[[#y]]243; CHECK: OpFunctionEnd244 245define spir_func float @TestCopysign(float %x, float %y) local_unnamed_addr {246entry:247 %t = tail call float @llvm.copysign.f32(float %x, float %y)248 ret float %t249}250 251declare float @llvm.copysign.f32(float, float)252 253; CHECK: OpFunction254; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] floor255; CHECK: OpFunctionEnd256 257define spir_func float @TestFloor(float %x) local_unnamed_addr {258entry:259 %t = tail call float @llvm.floor.f32(float %x)260 ret float %t261}262 263declare float @llvm.floor.f32(float)264 265; CHECK: OpFunction266; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] trunc267; CHECK: OpFunctionEnd268 269define spir_func float @TestTrunc(float %x) local_unnamed_addr {270entry:271 %t = tail call float @llvm.trunc.f32(float %x)272 ret float %t273}274 275declare float @llvm.trunc.f32(float)276 277; CHECK: OpFunction278; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] rint279; CHECK: OpFunctionEnd280 281define spir_func float @TestRint(float %x) local_unnamed_addr {282entry:283 %t = tail call float @llvm.rint.f32(float %x)284 ret float %t285}286 287declare float @llvm.rint.f32(float)288 289;; It is intentional that nearbyint translates to rint.290; CHECK: OpFunction291; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] rint292; CHECK: OpFunctionEnd293 294define spir_func float @TestNearbyint(float %x) local_unnamed_addr {295entry:296 %t = tail call float @llvm.nearbyint.f32(float %x)297 ret float %t298}299 300declare float @llvm.nearbyint.f32(float)301 302; CHECK: OpFunction303; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] round304; CHECK: OpFunctionEnd305 306define spir_func float @TestRound(float %x) local_unnamed_addr {307entry:308 %t = tail call float @llvm.round.f32(float %x)309 ret float %t310}311 312declare float @llvm.round.f32(float)313 314;; It is intentional that roundeven translates to rint.315; CHECK: OpFunction316; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] rint317; CHECK: OpFunctionEnd318 319define spir_func float @TestRoundEven(float %x) local_unnamed_addr {320entry:321 %t = tail call float @llvm.roundeven.f32(float %x)322 ret float %t323}324 325declare float @llvm.roundeven.f32(float)326 327; CHECK: OpFunction328; CHECK: %[[#x:]] = OpFunctionParameter %[[#]]329; CHECK: %[[#y:]] = OpFunctionParameter %[[#]]330; CHECK: %[[#z:]] = OpFunctionParameter %[[#]]331; CHECK: %[[#]] = OpExtInst %[[#var1]] %[[#extinst_id]] fma %[[#x]] %[[#y]] %[[#z]]332; CHECK: OpFunctionEnd333 334define spir_func float @TestFma(float %x, float %y, float %z) {335entry:336 %t = tail call float @llvm.fma.f32(float %x, float %y, float %z)337 ret float %t338}339 340declare float @llvm.fma.f32(float, float, float)341 342; CHECK: OpFunction343; CHECK: %[[#d:]] = OpFunctionParameter %[[#]]344; CHECK: %[[#fracPtr:]] = OpFunctionParameter %[[#]]345; CHECK: %[[#integralPtr:]] = OpFunctionParameter %[[#]]346; CHECK: %[[#varPtr:]] = OpVariable %[[#]] Function347; CHECK: %[[#frac:]] = OpExtInst %[[#var2]] %[[#extinst_id]] modf %[[#d]] %[[#varPtr]]348; CHECK: %[[#integral:]] = OpLoad %[[#var2]] %[[#varPtr]]349; CHECK: OpStore %[[#fracPtr]] %[[#frac]]350; CHECK: OpStore %[[#integralPtr]] %[[#integral]]351; CHECK: OpFunctionEnd352define void @TestModf(double %d, ptr addrspace(1) %frac, ptr addrspace(1) %integral) {353entry:354 %4 = tail call { double, double } @llvm.modf.f64(double %d)355 %5 = extractvalue { double, double } %4, 0356 %6 = extractvalue { double, double } %4, 1357 store double %5, ptr addrspace(1) %frac, align 8358 store double %6, ptr addrspace(1) %integral, align 8359 ret void360}361 362; CHECK: OpFunction363; CHECK: %[[#d:]] = OpFunctionParameter %[[#]]364; CHECK: %[[#fracPtr:]] = OpFunctionParameter %[[#]]365; CHECK: %[[#integralPtr:]] = OpFunctionParameter %[[#]]366; CHECK: %[[#entryBlock:]] = OpLabel367; CHECK: %[[#varPtr:]] = OpVariable %[[#]] Function368; CHECK: OpBranchConditional %[[#]] %[[#lor_lhs_falseBlock:]] %[[#if_thenBlock:]]369; CHECK: %[[#lor_lhs_falseBlock]] = OpLabel370; CHECK: OpBranchConditional %[[#]] %[[#if_endBlock:]] %[[#if_thenBlock]]371; CHECK: %[[#if_thenBlock]] = OpLabel372; CHECK: OpBranch %[[#returnBlock:]]373; CHECK: %[[#if_endBlock]] = OpLabel374; CHECK: %[[#frac:]] = OpExtInst %[[#var2]] %[[#extinst_id]] modf %[[#d]] %[[#varPtr]]375; CHECK: %[[#integral:]] = OpLoad %[[#var2]] %[[#varPtr]]376; CHECK: OpStore %[[#fracPtr]] %[[#frac]]377; CHECK: OpStore %[[#integralPtr]] %[[#integral]]378; CHECK: OpFunctionEnd379define dso_local void @TestModf2(double noundef %d, ptr noundef %frac, ptr noundef %integral) {380entry:381 %0 = load ptr, ptr %frac, align 8382 %tobool = icmp ne ptr %0, null383 br i1 %tobool, label %lor.lhs.false, label %if.then384 385lor.lhs.false:386 %1 = load ptr, ptr %integral, align 8387 %tobool1 = icmp ne ptr %1, null388 br i1 %tobool1, label %if.end, label %if.then389 390if.then:391 br label %return392 393if.end:394 %6 = tail call { double, double } @llvm.modf.f64(double %d)395 %7 = extractvalue { double, double } %6, 0396 %8 = extractvalue { double, double } %6, 1397 store double %7, ptr %frac, align 4398 store double %8, ptr %integral, align 4399 br label %return400 401return:402 ret void403}404 405declare { double, double } @llvm.modf.f64(double)406