brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.6 KiB · bd9a62f Raw
346 lines · plain
1// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -fnative-int16-type -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s2 3struct S {4  int X;5  float Y;6};7 8// struct truncation to a scalar9// CHECK-LABEL: define void {{.*}}call010// CHECK: [[s:%.*]] = alloca %struct.S, align 111// CHECK-NEXT: [[A:%.*]] = alloca i32, align 412// CHECK-NEXT: [[Tmp:%.*]] = alloca %struct.S, align 113// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[s]], ptr align 1 {{.*}}, i32 8, i1 false)14// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[Tmp]], ptr align 1 [[s]], i32 8, i1 false)15// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[Tmp]], i32 0, i32 016// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[Tmp]], i32 0, i32 117// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G1]], align 418// CHECK-NEXT: store i32 [[L]], ptr [[A]], align 419export void call0() {20  S s = {1,2};21  int A = (int)s;22}23 24// struct from vector25// CHECK-LABEL: define void {{.*}}call126// CHECK: [[A:%.*]] = alloca <2 x i32>, align 827// CHECK-NEXT: [[s:%.*]] = alloca %struct.S, align 128// CHECK-NEXT: store <2 x i32> <i32 1, i32 2>, ptr [[A]], align 829// CHECK-NEXT: [[L:%.*]] = load <2 x i32>, ptr [[A]], align 830// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 031// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 132// CHECK-NEXT: [[VL:%.*]] = extractelement <2 x i32> [[L]], i64 033// CHECK-NEXT: store i32 [[VL]], ptr [[G1]], align 434// CHECK-NEXT: [[VL2:%.*]] = extractelement <2 x i32> [[L]], i64 135// CHECK-NEXT: [[C:%.*]] = sitofp i32 [[VL2]] to float36// CHECK-NEXT: store float [[C]], ptr [[G2]], align 437export void call1() {38  int2 A = {1,2};39  S s = (S)A;40}41 42 43// struct from array44// CHECK-LABEL: define void {{.*}}call245// CHECK: [[A:%.*]] = alloca [2 x i32], align 446// CHECK-NEXT: [[s:%.*]] = alloca %struct.S, align 147// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 448// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 8, i1 false)49// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false)50// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 051// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 152// CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 053// CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 154// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G3]], align 455// CHECK-NEXT: store i32 [[L]], ptr [[G1]], align 456// CHECK-NEXT: [[L4:%.*]] = load i32, ptr [[G4]], align 457// CHECK-NEXT: [[C:%.*]] = sitofp i32 [[L4]] to float58// CHECK-NEXT: store float [[C]], ptr [[G2]], align 459export void call2() {60  int A[2] = {1,2};61  S s = (S)A;62}63 64struct Q {65  int Z;66};67 68struct R {69  Q q;70  float F;71};72 73// struct from nested struct?74// CHECK-LABEL: define void {{.*}}call675// CHECK: [[r:%.*]] = alloca %struct.R, align 176// CHECK-NEXT: [[s:%.*]] = alloca %struct.S, align 177// CHECK-NEXT: [[Tmp:%.*]] = alloca %struct.R, align 178// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[r]], ptr align 1 {{.*}}, i32 8, i1 false)79// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[Tmp]], ptr align 1 [[r]], i32 8, i1 false)80// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 081// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 182// CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds %struct.R, ptr [[Tmp]], i32 0, i32 083// CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds %struct.R, ptr [[Tmp]], i32 0, i32 184// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G3]], align 485// CHECK-NEXT: store i32 [[L]], ptr [[G1]], align 486// CHECK-NEXT: [[L4:%.*]] = load float, ptr [[G4]], align 487// CHECK-NEXT: store float [[L4]], ptr [[G2]], align 488export void call6() {89  R r = {{1}, 2.0};90  S s = (S)r;91}92 93// nested struct from array?94// CHECK-LABEL: define void {{.*}}call795// CHECK: [[A:%.*]] = alloca [2 x i32], align 496// CHECK-NEXT: [[r:%.*]] = alloca %struct.R, align 197// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 498// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 8, i1 false)99// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false)100// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.R, ptr [[r]], i32 0, i32 0101// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.R, ptr [[r]], i32 0, i32 1102// CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 0103// CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 1104// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G3]], align 4105// CHECK-NEXT: store i32 [[L]], ptr [[G1]], align 4106// CHECK-NEXT: [[L4:%.*]] = load i32, ptr [[G4]], align 4107// CHECK-NEXT: [[C:%.*]] = sitofp i32 [[L4]] to float108// CHECK-NEXT: store float [[C]], ptr [[G2]], align 4109export void call7() {110  int A[2] = {1,2};111  R r = (R)A;112}113 114struct T {115  int A;116  int B;117  int C;118};119 120// struct truncation121// CHECK-LABEL: define void {{.*}}call8122// CHECK: [[t:%.*]] = alloca %struct.T, align 1123// CHECK-NEXT: [[s:%.*]] = alloca %struct.S, align 1124// CHECK-NEXT: [[Tmp:%.*]] = alloca %struct.T, align 1125// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[t]], ptr align 1 {{.*}}, i32 12, i1 false)126// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[Tmp]], ptr align 1 [[t]], i32 12, i1 false)127// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 0128// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 1129// CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds %struct.T, ptr [[Tmp]], i32 0, i32 0130// CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds %struct.T, ptr %agg-temp, i32 0, i32 1131// CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds %struct.T, ptr %agg-temp, i32 0, i32 2132// CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[G3]], align 4133// CHECK-NEXT: store i32 [[L1]], ptr [[G1]], align 4134// CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[G4]], align 4135// CHECK-NEXT: [[C:%.*]] = sitofp i32 [[L2]] to float136// CHECK-NEXT: store float [[C]], ptr [[G2]], align 4137export void call8() {138  T t = {1,2,3};139  S s = (S)t;140}141 142struct BFields {143  double D;144  int E: 15;145  int : 8;146  float F;147};148 149struct Derived : BFields {150  int G;151};152 153// Derived Struct truncate to scalar154// CHECK-LABEL: call9155// CHECK: [[D2:%.*]] = alloca double, align 8156// CHECK-NEXT: [[Tmp:%.*]] = alloca %struct.Derived, align 1157// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[Tmp]], ptr align 1 %D, i32 19, i1 false)158// CHECK-NEXT: [[Gep:%.*]] = getelementptr inbounds %struct.Derived, ptr [[Tmp]], i32 0, i32 0159// CHECK-NEXT: [[E:%.*]] = getelementptr inbounds nuw %struct.BFields, ptr [[Gep]], i32 0, i32 1160// CHECK-NEXT: [[Gep1:%.*]] = getelementptr inbounds %struct.Derived, ptr [[Tmp]], i32 0, i32 0, i32 0161// CHECK-NEXT: [[Gep2:%.*]] = getelementptr inbounds %struct.Derived, ptr [[Tmp]], i32 0, i32 0, i32 2162// CHECK-NEXT: [[Gep3:%.*]] = getelementptr inbounds %struct.Derived, ptr [[Tmp]], i32 0, i32 1163// CHECK-NEXT: [[A:%.*]] = load double, ptr [[Gep1]], align 8164// CHECK-NEXT: store double [[A]], ptr [[D2]], align 8165// CHECK-NEXT: ret void166export void call9(Derived D) {167  double D2 = (double)D;168}169 170// Derived struct from vector171// CHECK-LABEL: call10172// CHECK: [[IAddr:%.*]] = alloca <4 x i32>, align 16173// CHECK-NEXT: [[D:%.*]] = alloca %struct.Derived, align 1174// CHECK-NEXT: store <4 x i32> %I, ptr [[IAddr]], align 16175// CHECK-NEXT: [[A:%.*]] = load <4 x i32>, ptr [[IAddr]], align 16176// CHECK-NEXT: [[Gep:%.*]] = getelementptr inbounds %struct.Derived, ptr [[D]], i32 0, i32 0177// CHECK-NEXT: [[E:%.*]] = getelementptr inbounds nuw %struct.BFields, ptr [[Gep]], i32 0, i32 1178// CHECK-NEXT: [[Gep1:%.*]] = getelementptr inbounds %struct.Derived, ptr [[D]], i32 0, i32 0, i32 0179// CHECK-NEXT: [[Gep2:%.*]] = getelementptr inbounds %struct.Derived, ptr [[D]], i32 0, i32 0, i32 2180// CHECK-NEXT: [[Gep3:%.*]] = getelementptr inbounds %struct.Derived, ptr [[D]], i32 0, i32 1181// CHECK-NEXT: [[VL:%.*]] = extractelement <4 x i32> [[A]], i64 0182// CHECK-NEXT: [[C:%.*]] = sitofp i32 [[VL]] to double183// CHECK-NEXT: store double [[C]], ptr [[Gep1]], align 8184// CHECK-NEXT: [[VL4:%.*]] = extractelement <4 x i32> [[A]], i64 1185// CHECK-NEXT: [[B:%.*]] = trunc i32 [[VL4]] to i24186// CHECK-NEXT: [[BFL:%.*]] = load i24, ptr [[E]], align 1187// CHECK-NEXT: [[BFV:%.*]] = and i24 [[B]], 32767188// CHECK-NEXT: [[BFC:%.*]] = and i24 [[BFL]], -32768189// CHECK-NEXT: [[BFSet:%.*]] = or i24 [[BFC]], [[BFV]]190// CHECK-NEXT: store i24 [[BFSet]], ptr [[E]], align 1191// CHECK-NEXT: [[VL5:%.*]] = extractelement <4 x i32> [[A]], i64 2192// CHECK-NEXT: [[C6:%.*]] = sitofp i32 [[VL5]] to float193// CHECK-NEXT: store float [[C6]], ptr [[Gep2]], align 4194// CHECK-NEXT: [[VL7:%.*]] = extractelement <4 x i32> [[A]], i64 3195// CHECK-NEXT: store i32 [[VL7]], ptr [[Gep3]], align 4196// CHECK-NEXT: ret void197export void call10(int4 I) {198  Derived D = (Derived)I;199}200 201// truncate derived struct202// CHECK-LABEL: call11203// CHECK: [[B:%.*]] = alloca %struct.BFields, align 1204// CHECK-NEXT: [[Tmp:%.*]] = alloca %struct.Derived, align 1205// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[Tmp]], ptr align 1 [[D]], i32 19, i1 false)206// CHECK-NEXT: [[Gep:%.*]] = getelementptr inbounds %struct.BFields, ptr [[B]], i32 0207// CHECK-NEXT: [[E:%.*]] = getelementptr inbounds nuw %struct.BFields, ptr [[Gep]], i32 0, i32 1208// CHECK-NEXT: [[Gep1:%.*]] = getelementptr inbounds %struct.BFields, ptr [[B]], i32 0, i32 0209// CHECK-NEXT: [[Gep2:%.*]] = getelementptr inbounds %struct.BFields, ptr [[B]], i32 0, i32 2210// CHECK-NEXT: [[Gep3:%.*]] = getelementptr inbounds %struct.Derived, ptr [[Tmp]], i32 0, i32 0211// CHECK-NEXT: [[E4:%.*]] = getelementptr inbounds nuw %struct.BFields, ptr [[Gep3]], i32 0, i32 1212// CHECK-NEXT: [[Gep5:%.*]] = getelementptr inbounds %struct.Derived, ptr [[Tmp]], i32 0, i32 0, i32 0213// CHECK-NEXT: [[Gep6:%.*]] = getelementptr inbounds %struct.Derived, ptr [[Tmp]], i32 0, i32 0, i32 2214// CHECK-NEXT: [[Gep7:%.*]] = getelementptr inbounds %struct.Derived, ptr [[Tmp]], i32 0, i32 1215// CHECK-NEXT: [[A:%.*]] = load double, ptr [[Gep5]], align 8216// CHECK-NEXT: store double [[A]], ptr [[Gep1]], align 8217// CHECK-NEXT: [[BFl:%.*]] = load i24, ptr [[E4]], align 1218// CHECK-NEXT: [[Shl:%.*]] = shl i24 [[BFL]], 9219// CHECK-NEXT: [[Ashr:%.*]] = ashr i24 [[Shl]], 9220// CHECK-NEXT: [[BFC:%.*]] = sext i24 [[Ashr]] to i32221// CHECK-NEXT: [[B:%.*]] = trunc i32 [[BFC]] to i24222// CHECK-NEXT: [[BFL8:%.*]] = load i24, ptr [[E]], align 1223// CHECK-NEXT: [[BFV:%.*]] = and i24 [[B]], 32767224// CHECK-NEXT: [[BFC:%.*]] = and i24 [[BFL8]], -32768225// CHECK-NEXT: [[BFSet:%.*]] = or i24 [[BFC]], [[BFV]]226// CHECK-NEXT: store i24 [[BFSet]], ptr [[E]], align 1227// CHECK-NEXT: [[C:%.*]] = load float, ptr [[Gep6]], align 4228// CHECK-NEXT: store float [[C]], ptr [[Gep2]], align 4229// CHECK-NEXT: ret void230export void call11(Derived D) {231  BFields B = (BFields)D;232}233 234struct Empty {235};236 237// cast to an empty struct238// CHECK-LABEL: call12239// CHECK: [[I:%.*]] = alloca <4 x i32>, align 16240// CHECK-NEXT: [[E:%.*]] = alloca %struct.Empty, align 1241// CHECK-NEXT: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr [[I]], align 16242// CHECK-NEXT: [[A:%.*]] = load <4 x i32>, ptr [[I]], align 16243// CHECK-NEXt: ret void244export void call12() {245  int4 I = {1,2,3,4};246  Empty E = (Empty)I;247}248 249struct MoreBFields {250  int A;251  uint64_t B: 60;252  float C;253  uint16_t D: 10;254  uint16_t E: 6;255  int : 32;256  double F;257  int : 8;258  uint G;259};260 261// more complicated bitfield case262// CHECK-LABEL: call13263// CHECK: [[AA:%.*]] = alloca i32, align 4264// CHECK-NEXT: [[MBF:%.*]] = alloca %struct.MoreBFields, align 1265// CHECK-NEXT: store i32 %A, ptr [[AA]], align 4266// CHECK-NEXT: [[Z:%.*]] = load i32, ptr [[AA]], align 4267// get the gep for the struct.268// CHECK-NEXT: [[Gep:%.*]] = getelementptr inbounds %struct.MoreBFields, ptr [[MBF]], i32 0269// CHECK-NEXT: [[FieldB:%.*]] = getelementptr inbounds nuw %struct.MoreBFields, ptr [[Gep]], i32 0, i32 1270// D and E share the same field index271// CHECK-NEXT: [[FieldD:%.*]] = getelementptr inbounds nuw %struct.MoreBFields, ptr [[Gep]], i32 0, i32 3272// CHECK-NEXT: [[FieldE:%.*]] = getelementptr inbounds nuw %struct.MoreBFields, ptr [[Gep]], i32 0, i32 3273// CHECK-NEXT: [[FieldA:%.*]] = getelementptr inbounds %struct.MoreBFields, ptr [[MBF]], i32 0, i32 0274// CHECK-NEXT: [[FieldC:%.*]] = getelementptr inbounds %struct.MoreBFields, ptr [[MBF]], i32 0, i32 2275// CHECK-NEXT: [[FieldF:%.*]] = getelementptr inbounds %struct.MoreBFields, ptr [[MBF]], i32 0, i32 5276// CHECK-NEXT: [[FieldG:%.*]] = getelementptr inbounds %struct.MoreBFields, ptr [[MBF]], i32 0, i32 7277// store int A into field A278// CHECK-NEXT: store i32 [[Z]], ptr [[FieldA]], align 4279// store int A in bitField B, do necessary conversions280// CHECK-NEXT: [[Conv:%.*]] = sext i32 [[Z]] to i64281// CHECK-NEXT: [[BFL:%.*]] = load i64, ptr [[FieldB]], align 1282// CHECK-NEXT: [[BFV:%.*]] = and i64 [[Conv]], 1152921504606846975283// CHECK-NEXT: [[BFC:%.*]] = and i64 [[BFL]], -1152921504606846976284// CHECK-NEXT: [[BFS:%.*]] = or i64 [[BFC]], [[BFV]]285// CHECK-NEXT: store i64 [[BFS]], ptr [[FieldB]], align 1286// store int A into field C287// CHECK-NEXT: [[Conv5:%.*]] = sitofp i32 [[Z]] to float288// CHECK-NEXT: store float [[Conv5]], ptr [[FieldC]], align 4289// store int A into bitfield D290// CHECK-NEXT: [[Conv6:%.*]] = trunc i32 [[Z]] to i16291// CHECK-NEXT: [[FDL:%.*]] = load i16, ptr [[FieldD]], align 1292// CHECK-NEXT: [[FDV:%.*]] = and i16 [[Conv6]], 1023293// CHECK-NEXT: [[FDC:%.*]] = and i16 [[FDL]], -1024294// CHECK-NEXT: [[FDS:%.*]] = or i16 [[FDC]], [[FDV]]295// CHECK-NEXT: store i16 [[FDS]], ptr [[FieldD]], align 1296// store int A into bitfield E;297// CHECK-NEXT: [[Conv11:%.*]] = trunc i32 [[Z]] to i16298// CHECK-NEXT: [[FEL:%.*]] = load i16, ptr [[FieldE]], align 1299// CHECK-NEXT: [[FEV:%.*]] = and i16 [[Conv11]], 63300// CHECK-NEXT: [[FESHL:%.*]] = shl i16 [[FEV]], 10301// CHECK-NEXT: [[FEC:%.*]] = and i16 [[FEL]], 1023302// CHECK-NEXT: [[FES:%.*]] = or i16 [[FEC]], [[FESHL]]303// CHECK-NEXT: store i16 [[FES]], ptr [[FieldE]], align 1304// store int A into field F305// CHECK-NEXT: [[Conv16:%.*]] = sitofp i32 [[Z]] to double306// CHECK-NEXT: store double [[Conv16]], ptr [[FieldF]], align 8307// store int A into field G308// CHECK-NEXT: store i32 [[Z]], ptr [[FieldG]], align 4309// CHECK-NEXT: ret void310export void call13(int A) {311  MoreBFields MBF = (MoreBFields)A;312}313 314struct Inner {315  int Z;316  int Y : 25;317};318 319struct Outer {320  int A;321  Inner I;322};323 324// show usage of "extra" gep for struct containing bitfield325// CHECK-LABEL: call14326// CHECK: [[AA:%.*]] = alloca i32, align 4327// CHECK-NEXT: [[O:%.*]] = alloca %struct.Outer, align 1328// CHECK-NEXT: store i32 %A, ptr [[AA]], align 4329// CHECK-NEXT: [[Z:%.*]] = load i32, ptr [[AA]], align 4330// CHECK-NEXT: [[FieldA:%.*]] = getelementptr inbounds %struct.Outer, ptr [[O]], i32 0, i32 0331// showing real usage of "extra gep". need Inner struct to generate access of its bitfield.332// CHECK-NEXT: [[FieldI:%.*]] = getelementptr inbounds %struct.Outer, ptr [[O]], i32 0, i32 1333// CHECK-NEXT: [[FieldY:%.*]] = getelementptr inbounds nuw %struct.Inner, ptr [[FieldI]], i32 0, i32 1334// CHECK-NEXT: [[FieldZ:%.*]] = getelementptr inbounds %struct.Outer, ptr [[O]], i32 0, i32 1, i32 0335// CHECK-NEXT: store i32 [[Z]], ptr [[FieldA]], align 4336// CHECK-NEXT: store i32 [[Z]], ptr [[FieldZ]], align 4337// CHECK-NEXT: [[BFL:%.*]] = load i32, ptr [[FieldY]], align 1338// CHECK-NEXT: [[BFV:%.*]] = and i32 [[Z]], 33554431339// CHECK-NEXT: [[BFC:%.*]] = and i32 [[BFL]], -33554432340// CHECK-NEXT: [[BFS:%.*]] = or i32 [[BFC]], [[BFV]]341// CHECK-NEXT: store i32 [[BFS]], ptr [[FieldY]], align 1342// CHECK-NEXT: ret void343export void call14(int A) {344  Outer O = (Outer)A;345}346