brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.8 KiB · ec03804 Raw
331 lines · plain
1// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s --check-prefixes=CHECK,ALL2// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -O3 -emit-llvm -finclude-default-header -o - %s | FileCheck %s --check-prefixes=OPT,ALL3 4// Case 1: Simple floating integral conversion.5// In this test case a float value is passed to an inout parameter taking an6// integer. It is converted to an integer on call and converted back after the7// function.8 9// CHECK: define hidden void {{.*}}trunc_Param{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}})10void trunc_Param(inout int X) {}11 12// ALL-LABEL: define noundef nofpclass(nan inf) float {{.*}}case113// CHECK: [[F:%.*]] = alloca float14// CHECK: [[ArgTmp:%.*]] = alloca i3215// CHECK: [[FVal:%.*]] = load float, ptr {{.*}}16// CHECK: [[IVal:%.*]] = fptosi float [[FVal]] to i3217// CHECK: store i32 [[IVal]], ptr [[ArgTmp]]18// CHECK: call void {{.*}}trunc_Param{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) [[ArgTmp]])19// CHECK: [[IRet:%.*]] = load i32, ptr [[ArgTmp]]20// CHECK: [[FRet:%.*]] = sitofp i32 [[IRet]] to float21// CHECK: store float [[FRet]], ptr [[F]]22// OPT: [[IVal:%.*]] = fptosi float {{.*}} to i3223// OPT: [[FVal:%.*]] = sitofp i32 [[IVal]] to float24// OPT: ret float [[FVal]]25export float case1(float F) {26  trunc_Param(F);27  return F;28}29 30// Case 2: Uninitialized `out` parameters.31// `out` parameters are not pre-initialized by the caller, so they are32// uninitialized in the function. If they are not initialized before the33// function returns the value is undefined.34 35// CHECK: define hidden void {{.*}}undef{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}})36void undef(out int Z) { }37 38// ALL-LABEL: define noundef i32 {{.*}}case239// CHECK: [[V:%.*]] = alloca i3240// CHECK: [[ArgTmp:%.*]] = alloca i3241// CHECK-NOT: store {{.*}}, ptr [[ArgTmp]]42// CHECK: call void {{.*}}unde{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) [[ArgTmp]])43// CHECK-NOT: store {{.*}}, ptr [[ArgTmp]]44// CHECK: [[Res:%.*]] = load i32, ptr [[ArgTmp]]45// CHECK: store i32 [[Res]], ptr [[V]], align 446// OPT: ret i32 undef47export int case2() {48  int V;49  undef(V);50  return V;51}52 53// Case 3: Simple initialized `out` parameter.54// This test should verify that an out parameter value is written to as55// expected.56 57// CHECK: define hidden void {{.*}}zero{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}})58void zero(out int Z) { Z = 0; }59 60// ALL-LABEL: define noundef i32 {{.*}}case361// CHECK: [[V:%.*]] = alloca i3262// CHECK: [[ArgTmp:%.*]] = alloca i3263// CHECK-NOT: store {{.*}}, ptr [[ArgTmp]]64// CHECK: call void {{.*}}zero{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) [[ArgTmp]])65// CHECK-NOT: store {{.*}}, ptr [[ArgTmp]]66// CHECK: [[Res:%.*]] = load i32, ptr [[ArgTmp]]67// CHECK: store i32 [[Res]], ptr [[V]], align 468// OPT: ret i32 069export int case3() {70  int V;71  zero(V);72  return V;73}74 75// Case 4: Vector swizzle arguments.76// Vector swizzles in HLSL produce lvalues, so they can be used as arguments to77// inout parameters and the swizzle is reversed on writeback.78 79// CHECK: define hidden void {{.*}}funky{{.*}}(ptr noalias noundef nonnull align 16 dereferenceable(16) {{%.*}})80void funky(inout int3 X) {81  X.x += 1;82  X.y += 2;83  X.z += 3;84}85 86// ALL-LABEL: define noundef {{.*}}<3 x i32> {{.*}}case487 88// This block initializes V = 0.xxx.89// CHECK:  [[V:%.*]] = alloca <3 x i32>90// CHECK:  [[ArgTmp:%.*]] = alloca <3 x i32>91// CHECK:  store <1 x i32> zeroinitializer, ptr [[ZeroPtr:%.*]]92// CHECK:  [[ZeroV1:%.*]] = load <1 x i32>, ptr [[ZeroPtr]]93// CHECK:  [[ZeroV3:%.*]] = shufflevector <1 x i32> [[ZeroV1]], <1 x i32> poison, <3 x i32> zeroinitializer94// CHECK:  store <3 x i32> [[ZeroV3]], ptr [[V]]95 96// Shuffle the vector to the temporary.97// CHECK:  [[VVal:%.*]] = load <3 x i32>, ptr [[V]]98// CHECK:  [[Vyzx:%.*]] = shufflevector <3 x i32> [[VVal]], <3 x i32> poison, <3 x i32> <i32 1, i32 2, i32 0>99// CHECK:  store <3 x i32> [[Vyzx]], ptr [[ArgTmp]]100 101// Call the function with the temporary.102// CHECK: call void {{.*}}funky{{.*}}(ptr noalias noundef nonnull align 16 dereferenceable(16) [[ArgTmp]])103 104// Write it back.105// CHECK:  [[RetVal:%.*]] = load <3 x i32>, ptr [[ArgTmp]]106// CHECK:  [[Src0:%.*]] = extractelement <3 x i32> [[RetVal]], i32 0107// CHECK:  [[PtrY:%.*]] = getelementptr <3 x i32>, ptr %V, i32 0, i32 1108// CHECK:  store i32 [[Src0]], ptr [[PtrY]], align 4109// CHECK:  [[Src1:%.*]] = extractelement <3 x i32> [[RetVal]], i32 1110// CHECK:  [[PtrZ:%.*]] = getelementptr <3 x i32>, ptr %V, i32 0, i32 2111// CHECK:  store i32 [[Src1]], ptr [[PtrZ]], align 4112// CHECK:  [[Src2:%.*]] = extractelement <3 x i32> [[RetVal]], i32 2113// CHECK:  store i32 [[Src2]], ptr %V, align 4114 115// OPT: ret <3 x i32> <i32 3, i32 1, i32 2>116export int3 case4() {117  int3 V = 0.xxx;118  funky(V.yzx);119  return V;120}121 122 123// Case 5: Straightforward inout of a scalar value.124 125// CHECK: define hidden void {{.*}}increment{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}})126void increment(inout int I) {127  I += 1;128}129 130// ALL-LABEL: define noundef i32 {{.*}}case5131 132// CHECK: [[I:%.*]] = alloca i32133// CHECK: [[ArgTmp:%.*]] = alloca i32134// CHECK: store i32 4, ptr [[I]]135// CHECK: [[IInit:%.*]] = load i32, ptr [[I]]136// CHECK: store i32 [[IInit:%.*]], ptr [[ArgTmp]], align 4137// CHECK: call void {{.*}}increment{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) [[ArgTmp]])138// CHECK: [[RetVal:%.*]] = load i32, ptr [[ArgTmp]]139// CHECK: store i32 [[RetVal]], ptr [[I]], align 4140// OPT: ret i32 5141export int case5() {142  int I = 4;143  increment(I);144  return I;145}146 147// Case 6: Aggregate out parameters.148struct S {149  int X;150  float Y;151};152 153// CHECK: define hidden void {{.*}}init{{.*}}(ptr noalias noundef nonnull align 1 dereferenceable(8) {{%.*}})154void init(out S s) {155  s.X = 3;156  s.Y = 4;157}158 159// ALL-LABEL: define noundef i32 {{.*}}case6160 161// CHECK: [[S:%.*]] = alloca %struct.S162// CHECK: [[Tmp:%.*]] = alloca %struct.S163// CHECK: call void {{.*}}init{{.*}}(ptr noalias noundef nonnull align 1 dereferenceable(8) [[Tmp]])164// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[S]], ptr align 1 [[Tmp]], i32 8, i1 false)165 166// OPT: ret i32 7167export int case6() {168  S s;169  init(s);170  return s.X + s.Y;171}172 173// Case 7: Aggregate inout parameters.174struct R {175  int X;176  float Y;177};178 179// CHECK: define hidden void {{.*}}init{{.*}}(ptr noalias noundef nonnull align 1 dereferenceable(8) {{%.*}})180void init(inout R s) {181  s.X = 3;182  s.Y = 4;183}184 185// ALL-LABEL: define noundef i32 {{.*}}case7186 187// CHECK: [[S:%.*]] = alloca %struct.R188// CHECK: [[Tmp:%.*]] = alloca %struct.R189// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[Tmp]], ptr align 1 [[S]], i32 8, i1 false)190// CHECK: call void {{.*}}init{{.*}}(ptr noalias noundef nonnull align 1 dereferenceable(8) [[Tmp]])191// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[S]], ptr align 1 [[Tmp]], i32 8, i1 false)192 193// OPT: ret i32 7194export int case7() {195  R s;196  init(s);197  return s.X + s.Y;198}199 200 201// Case 8: Non-scalars with a cast expression.202 203// CHECK: define hidden void {{.*}}trunc_vec{{.*}}(ptr noalias noundef nonnull align 16 dereferenceable(16) {{%.*}})204void trunc_vec(inout int3 V) {}205 206// ALL-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}case8207 208// CHECK: [[V:%.*]] = alloca <3 x float>209// CHECK: [[Tmp:%.*]] = alloca <3 x i32>210// CHECK: [[FVal:%.*]] = load <3 x float>, ptr [[V]]211// CHECK: [[IVal:%.*]] = fptosi <3 x float> [[FVal]] to <3 x i32>212// CHECK: store <3 x i32> [[IVal]], ptr [[Tmp]]213// CHECK: call void {{.*}}trunc_vec{{.*}}(ptr noalias noundef nonnull align 16 dereferenceable(16) [[Tmp]])214// CHECK: [[IRet:%.*]] = load <3 x i32>, ptr [[Tmp]]215// CHECK: [[FRet:%.*]] = sitofp <3 x i32> [[IRet]] to <3 x float>216// CHECK: store <3 x float> [[FRet]], ptr [[V]]217 218// OPT: [[IVal:%.*]] = fptosi <3 x float> {{.*}} to <3 x i32>219// OPT: [[FVal:%.*]] = sitofp <3 x i32> [[IVal]] to <3 x float>220// OPT: ret <3 x float> [[FVal]]221 222export float3 case8(float3 V) {223  trunc_vec(V);224  return V;225}226 227// Case 9: Side-effecting lvalue argument expression!228 229void do_nothing(inout int V) {}230 231// ALL-LABEL: define noundef i32 {{.*}}case9232// CHECK: [[V:%.*]] = alloca i32233// CHECK: [[Tmp:%.*]] = alloca i32234// CHECK: store i32 0, ptr [[V]]235// CHECK: [[VVal:%.*]] = load i32, ptr [[V]]236// CHECK: [[VInc:%.*]] = add nsw i32 [[VVal]], 1237// CHECK: store i32 [[VInc]], ptr [[V]]238// CHECK: [[VArg:%.*]] = load i32, ptr [[V]]239// CHECK-NOT: add240// CHECK: store i32 [[VArg]], ptr [[Tmp]]241// CHECK: call void {{.*}}do_nothing{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) [[Tmp]])242// CHECK: [[RetVal:%.*]] = load i32, ptr [[Tmp]]243// CHECK: store i32 [[RetVal]], ptr [[V]]244 245// OPT: ret i32 1246export int case9() {247  int V = 0;248  do_nothing(++V);249  return V;250}251 252// Case 10: Verify argument writeback ordering for aliasing arguments.253 254void order_matters(inout int X, inout int Y) {255  Y = 2;256  X = 1;257}258 259// ALL-LABEL: define noundef i32 {{.*}}case10260 261// CHECK: [[V:%.*]] = alloca i32262// CHECK: [[Tmp0:%.*]] = alloca i32263// CHECK: [[Tmp1:%.*]] = alloca i32264// CHECK: store i32 0, ptr [[V]]265// CHECK: [[VVal:%.*]] = load i32, ptr [[V]]266// CHECK: store i32 [[VVal]], ptr [[Tmp0]]267// CHECK: [[VVal:%.*]] = load i32, ptr [[V]]268// CHECK: store i32 [[VVal]], ptr [[Tmp1]]269// CHECK: call void {{.*}}order_matters{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) [[Tmp0]], ptr noalias noundef nonnull align 4 dereferenceable(4) [[Tmp1]])270// CHECK: [[Arg1Val:%.*]] = load i32, ptr [[Tmp0]]271// CHECK: store i32 [[Arg1Val]], ptr [[V]]272// CHECK: [[Arg2Val:%.*]] = load i32, ptr [[Tmp1]]273// CHECK: store i32 [[Arg2Val]], ptr [[V]]274 275// OPT: ret i32 2276export int case10() {277  int V = 0;278  order_matters(V, V);279  return V;280}281 282// Case 11: Verify inout on bitfield lvalues283 284struct B {285  int X : 8;286  int Y : 8;287};288 289void setFour(inout int I) {290  I = 4;291}292 293// ALL-LABEL: define {{.*}} i32 {{.*}}case11294 295// CHECK: [[B:%.*]] = alloca %struct.B296// CHECK: [[Tmp:%.*]] = alloca i32297 298// CHECK: [[BFLoad:%.*]] = load i8, ptr [[B]]299// CHECK: [[BFcast:%.*]] = sext i8 [[BFLoad]] to i32300// CHECK: store i32 [[BFcast]], ptr [[Tmp]]301// CHECK: call void {{.*}}setFour{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) [[Tmp]])302// CHECK: [[RetVal:%.*]] = load i32, ptr [[Tmp]]303// CHECK: [[TruncVal:%.*]] = trunc i32 [[RetVal]] to i8304// CHECK: store i8 [[TruncVal]], ptr [[B]]305 306// OPT: ret i32 8307export int case11() {308  B b = {1 , 2};309  setFour(b.X);310  return b.X * b.Y;311}312 313// Case 12: Uninitialized out parameters are undefined314 315void oops(out int X) {}316// ALL-LABEL: define {{.*}} i32 {{.*}}case12317 318// CHECK: [[V:%.*]] = alloca i32319// CHECK: [[Tmp:%.*]] = alloca i32320// CHECK-NOT: store {{.*}}, ptr [[Tmp]]321// CHECK: call void {{.*}}oops{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) [[Tmp]])322// CHECK: [[ArgVal:%.*]] = load i32, ptr [[Tmp]]323// CHECK: store i32 [[ArgVal]], ptr [[V]]324 325// OPT:  ret i32 undef326export int case12() {327  int V = 0;328  oops(V);329  return V;330}331