brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.0 KiB · a95f68b Raw
376 lines · plain
1; RUN: llc < %s -mtriple s390x-ibm-zos | FileCheck %s2; Source to regenerate:3; struct Foo {4;   int * __ptr32 p32;5;   int *p64;6;   char *cp64;7; };8; void use_foo(Foo *f);9;10; // Assiging a ptr32 value to a 64-bit pointer11; void ptr32_to_ptr(Foo *f, int * __ptr32 i) {12;   f->p64 = i;13;   use_foo(f);14; }15;16; // Assigning a 64-bit ptr value to a ptr3217; void ptr_to_ptr32(Foo *f, int *i) {18;   f->p32 = i;19;   use_foo(f);20; }21;22; // Assigning a ptr32 value to a ptr32 value23; void ptr32_to_ptr32(Foo *f, int * __ptr32 i) {24;   f->p32 = i;25;   use_foo(f);26; }27;28; void ptr_to_ptr(Foo *f, int *i) {29;   f->p64 = i;30;   use_foo(f);31; }32;33; void test_indexing(Foo *f) {34;  f->cp64 = ((char * __ptr32 *)1028)[1];35;  use_foo(f);36; }37;38; void test_indexing_2(Foo *f) {39;   f->cp64 = ((char *** __ptr32 *)1028)[1][2][3];40;   use_foo(f);41; }42;43; unsigned long* test_misc() {44;   unsigned long* x = (unsigned long*)((char***** __ptr32*)1208)[0][11][1][113][149];45;   return x;46; }47;48; char* __ptr32* __ptr32 test_misc_2() {49;   static char* __ptr32* __ptr32 res = 0;50;   if (res == 0) {51;     res = ((char* __ptr32* __ptr32* __ptr32* __ptr32*)0)[4][136][6];52;   }53;   return res;54; }55;56; unsigned short test_misc_3() {57;   unsigned short this_asid = ((unsigned short*)(*(char* __ptr32*)(0x224)))[18];58;   return this_asid;59; }60;61; int test_misc_4() {62;   int a = (*(int*)(80 + ((char**** __ptr32*)1208)[0][11][1][123]) > 0x040202FF);63;   return a;64; }65;66; void test_misc_5(struct Foo *f) {67;   f->cp64  = *(char* __ptr32 *)(PSA_PTR + PSAAOLD);68;   use_foo(f);69; }70;71; int get_processor_count() {72;  return ((char * __ptr32 * __ptr32 *)0)[4][165][53];73; }74;75; void spill_ptr32_args_to_registers( char *__ptr32 p ) {76;   void g ( int, ... );77;   g ( 5, p, p, p, p, p );78; }79;80; $ clang -cc1 -triple s390x-ibm-zos -fzos-extensions -O2 -S t.cpp81;82; For the last test case:83;84;#include <stdlib.h>85;86;int foo();87;88;typedef struct qa_area {/* Area descriptor                */89;  char* __ptr32 text;           /* Start address of area          */90;  int length;      /* Size of area in bytes          */91;} qa_area;92;93;int main() {94;  qa_area* __ptr32 fap_asm_option_a = (qa_area*)__malloc31(sizeof(qa_area));95;96;  //((qa_area*)fap_asm_option_a)->length   = foo(); //PASSES97;  fap_asm_option_a->length = foo();                 //CRASHES98;  return 0;99;}100 101%struct.Foo = type { ptr addrspace(1), ptr, ptr }102declare void @use_foo(ptr)103 104define void @ptr32_to_ptr(ptr %f, ptr addrspace(1) %i) {105entry:106; CHECK-LABEL: ptr32_to_ptr:107; CHECK:       llgtr 0,2108; CHECK-NEXT:  stg   0,8(1)109  %0 = addrspacecast ptr addrspace(1) %i to ptr110  %p64 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 1111  store ptr %0, ptr %p64, align 8112  tail call void @use_foo(ptr %f)113  ret void114}115 116define void @ptr_to_ptr32(ptr %f, ptr %i) {117entry:118; CHECK-LABEL: ptr_to_ptr32:119; CHECK:       nilh 2,32767120; CHECK-NEXT:  st   2,0(1)121  %0 = addrspacecast ptr %i to ptr addrspace(1)122  %p32 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 0123  store ptr addrspace(1) %0, ptr %p32, align 8124  tail call void @use_foo(ptr %f)125  ret void126}127 128define void @ptr32_to_ptr32(ptr %f, ptr addrspace(1) %i) {129entry:130; CHECK-LABEL: ptr32_to_ptr32:131; CHECK:       st 2,0(1)132  %p32 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 0133  store ptr addrspace(1) %i, ptr %p32, align 8134  tail call void @use_foo(ptr %f)135  ret void136}137 138define void @ptr_to_ptr(ptr %f, ptr %i) {139; CHECK-LABEL: ptr_to_ptr:140; CHECK:       stg 2,8(1)141  %p64 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 1142  store ptr %i, ptr %p64, align 8143  tail call void @use_foo(ptr %f)144  ret void145}146 147define void @test_indexing(ptr %f) {148entry:149; CHECK-LABEL: test_indexing:150; CHECK:       l     0,1032151; CHECK:       llgtr 0,0152; CHECK:       stg   0,16(1)153  %0 = load ptr addrspace(1), ptr inttoptr (i64 1032 to ptr), align 8154  %1 = addrspacecast ptr addrspace(1) %0 to ptr155  %cp64 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 2156  store ptr %1, ptr %cp64, align 8157  tail call void @use_foo(ptr %f)158  ret void159}160 161define void @test_indexing_2(ptr %f) {162entry:163; CHECK-LABEL: test_indexing_2:164; CHECK:       lhi   0,16165; CHECK-NEXT:  a     0,1032166; CHECK-NEXT:  llgtr 2,0167; CHECK:       lg    0,24(2)168; CHECK:       stg   0,16(1)169  %0 = load ptr addrspace(1), ptr inttoptr (i64 1032 to ptr), align 8170  %arrayidx = getelementptr inbounds ptr, ptr addrspace(1) %0, i32 2171  %1 = load ptr, ptr addrspace(1) %arrayidx, align 8172  %arrayidx1 = getelementptr inbounds ptr, ptr %1, i64 3173  %2 = bitcast ptr %arrayidx1 to ptr174  %3 = load i64, ptr %2, align 8175  %cp64 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 2176  %4 = bitcast ptr %cp64 to ptr177  store i64 %3, ptr %4, align 8178  tail call void @use_foo(ptr %f)179  ret void180}181 182define ptr @test_misc() {183entry:184; CHECK-LABEL: test_misc:185; CHECK:       lhi   0,88186; CHECK-NEXT:  a     0,1208187; CHECK-NEXT:  llgtr 1,0188; CHECK-NEXT:  lg    1,0(1)189; CHECK-NEXT:  lg    1,8(1)190; CHECK-NEXT:  lg    1,904(1)191; CHECK-NEXT:  lg    3,1192(1)192  %0 = load ptr addrspace(1), ptr inttoptr (i64 1208 to ptr), align 8193  %arrayidx = getelementptr inbounds ptr, ptr addrspace(1) %0, i32 11194  %1 = load ptr, ptr addrspace(1) %arrayidx, align 8195  %arrayidx1 = getelementptr inbounds ptr, ptr %1, i64 1196  %2 = load ptr, ptr %arrayidx1, align 8197  %arrayidx2 = getelementptr inbounds ptr, ptr %2, i64 113198  %3 = load ptr, ptr %arrayidx2, align 8199  %arrayidx3 = getelementptr inbounds ptr, ptr %3, i64 149200  %4 = bitcast ptr %arrayidx3 to ptr201  %5 = load ptr, ptr %4, align 8202  ret ptr %5203}204 205define ptr addrspace(1) @test_misc_2() {206entry:207; CHECK-LABEL: test_misc_2:208; CHECK:       lhi   0,544209; CHECK:       a     0,16210; CHECK:       llgtr 1,0211; CHECK:       lhi   0,24212; CHECK:       a     0,0(1)213; CHECK:       llgtr 1,0214  %0 = load ptr addrspace(1), ptr inttoptr (i64 16 to ptr), align 16215  %arrayidx = getelementptr inbounds ptr addrspace(1), ptr addrspace(1) %0, i32 136216  %1 = load ptr addrspace(1), ptr addrspace(1) %arrayidx, align 4217  %arrayidx1 = getelementptr inbounds ptr addrspace(1), ptr addrspace(1) %1, i32 6218  %2 = load ptr addrspace(1), ptr addrspace(1) %arrayidx1, align 4219  ret ptr addrspace(1) %2220}221 222define zeroext i16 @test_misc_3() {223entry:224; CHECK-LABEL: test_misc_3:225; CHECK:       a     0,548226; CHECK-NEXT:  llgtr 1,0227; CHECK-NEXT:  llgh  3,0(1)228; CHECK-NEXT:  b     2(7)229  %0 = load ptr addrspace(1), ptr inttoptr (i64 548 to ptr), align 4230  %arrayidx2 = getelementptr inbounds i16, ptr addrspace(1) %0, i32 18231  %arrayidx = addrspacecast ptr addrspace(1) %arrayidx2 to ptr232  %1 = load i16, ptr %arrayidx, align 2233  ret i16 %1234}235 236define signext i32 @test_misc_4() {237entry:238; CHECK-LABEL: test_misc_4:239; CHECK:       lhi   0,88240; CHECK-NEXT:  a     0,1208241; CHECK-NEXT:  llgtr 1,0242; CHECK-NEXT:  lg    1,0(1)243; CHECK-NEXT:  lg    1,8(1)244; CHECK-NEXT:  lg    1,984(1)245; CHECK-NEXT:  iilf  0,67240703246; CHECK-NEXT:  c     0,80(1)247  %0 = load ptr addrspace(1), ptr inttoptr (i64 1208 to ptr), align 8248  %arrayidx = getelementptr inbounds ptr, ptr addrspace(1) %0, i32 11249  %1 = load ptr, ptr addrspace(1) %arrayidx, align 8250  %arrayidx1 = getelementptr inbounds ptr, ptr %1, i64 1251  %2 = load ptr, ptr %arrayidx1, align 8252  %arrayidx2 = getelementptr inbounds ptr, ptr %2, i64 123253  %3 = load ptr, ptr %arrayidx2, align 8254  %add.ptr = getelementptr inbounds i8, ptr %3, i64 80255  %4 = bitcast ptr %add.ptr to ptr256  %5 = load i32, ptr %4, align 4257  %cmp = icmp sgt i32 %5, 67240703258  %conv = zext i1 %cmp to i32259  ret i32 %conv260}261 262define void @test_misc_5(ptr %f) {263entry:264; CHECK-LABEL: test_misc_5:265; CHECK:       l     0,548266; CHECK-NEXT:  lg  6,8(5)267; CHECK-NEXT:  lg  5,0(5)268; CHECK-NEXT:  llgtr 0,0269; CHECK-NEXT:  stg   0,16(1)270  %0 = load ptr addrspace(1), ptr inttoptr (i64 548 to ptr), align 4271  %1 = addrspacecast ptr addrspace(1) %0 to ptr272  %cp64 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 2273  store ptr %1, ptr %cp64, align 8274  tail call void @use_foo(ptr %f)275  ret void276}277 278define signext i32 @get_processor_count() {279entry:280; CHECK-LABEL: get_processor_count:281; CHECK: lhi 0,660282; CHECK-NEXT: a 0,16283; CHECK-NEXT: llgtr 1,0284; CHECK-NEXT: lhi 0,53285; CHECK-NEXT: a 0,0(1)286; CHECK-NEXT: llgtr 1,0287; CHECK-NEXT: lgb 3,0(1)288  %0 = load ptr addrspace(1), ptr inttoptr (i64 16 to ptr), align 16289  %arrayidx = getelementptr inbounds ptr addrspace(1), ptr addrspace(1) %0, i32 165290  %1 = load ptr addrspace(1), ptr addrspace(1) %arrayidx, align 4291  %arrayidx1 = getelementptr inbounds i8, ptr addrspace(1) %1, i32 53292  %2 = load i8, ptr addrspace(1) %arrayidx1, align 1293  %conv = sext i8 %2 to i32294  ret i32 %conv295}296 297define void @spill_ptr32_args_to_registers(i8 addrspace(1)* %p) {298entry:299; CHECK-LABEL: spill_ptr32_args_to_registers:300; CHECK:         stmg 6,7,1872(4)301; CHECK-NEXT:    aghi 4,-192302; CHECK-NEXT:    lgr 2,1303; CHECK-NEXT:    lg 6,24(5)304; CHECK-NEXT:    lg 5,16(5)305; CHECK-NEXT:    stg 1,2216(4)306; CHECK-NEXT:    stg 1,2208(4)307; CHECK-NEXT:    lghi 1,5308; CHECK-NEXT:    stg 2,2200(4)309; CHECK-NEXT:    lgr 3,2310; CHECK-NEXT:    basr 7,6311; CHECK-NEXT:    bcr 0,0312; CHECK-NEXT:    lg 7,2072(4)313; CHECK-NEXT:    aghi 4,192314; CHECK-NEXT:    b 2(7)315  tail call void (i32, ...) @g(i32 noundef signext 5, ptr addrspace(1) noundef %p, ptr addrspace(1) noundef %p, ptr addrspace(1) noundef %p, ptr addrspace(1) noundef %p, ptr addrspace(1) noundef %p)316  ret void317}318declare void @g(i32 signext, ...)319 320; The resulting instructions may look odd on first view but it is a result of321; the C code. __malloc31() returns a 64 bit pointer, thus the sequence322;323;        la      1, 4(8)324;        llgtr   1, 1325;326; references the length attribute via the 64 bit pointer, and performs the327; cast to __ptr32, setting the upper 32 bit to zero.328;329define signext i32 @setlength() {330; CHECK-LABEL: setlength:331; CHECK: basr    7,6332; CHECK: lgr     [[MALLOC:[0-9]+]],3333; CHECK: basr    7,6334; CHECK: lgr     [[LENGTH:[0-9]+]],3335; CHECK: la      [[ADDR:[0-9]+]],4([[MALLOC]])336; CHECK: llgtr   [[ADDR]],[[ADDR]]337; CHECK: stg     [[LENGTH]],0([[ADDR]])338entry:339  %call = tail call ptr @__malloc31(i64 noundef 8)340  %call1 = tail call signext i32 @foo()341  %length = getelementptr inbounds i8, ptr %call, i64 4342  %0 = bitcast ptr %length to ptr343  %1 = addrspacecast ptr %0 to ptr addrspace(1)344  store i32 %call1, ptr addrspace(1) %1, align 4345  ret i32 0346}347 348; Same as test before, but this time calling349;  extern char* __ptr32 domalloc(unsigned long);350; instead of __malloc31(). Note the different instruction sequence, because351; the function now returns a __ptr32.352;353define signext i32 @setlength2() {354; CHECK-LABEL: setlength2:355; CHECK: basr    7,6356; CHECK: lgr     [[MALLOC:[0-9]+]],3357; CHECK: basr    7,6358; CHECK: lgr     [[LENGTH:[0-9]+]],3359; CHECK: ahi     [[MALLOC]],4360; CHECK: llgtr   [[ADDR]],[[MALLOC]]361; CHECK: stg     [[LENGTH]],0([[ADDR]])362entry:363  %call = tail call ptr addrspace(1) @domalloc(i64 noundef 8)364  %call1 = tail call signext i32 @foo()365  %length = getelementptr inbounds i8, ptr addrspace(1) %call, i32 4366  %0 = bitcast ptr addrspace(1) %length to ptr addrspace(1)367  store i32 %call1, ptr addrspace(1) %0, align 4368  ret i32 0369}370 371declare ptr @__malloc31(i64)372 373declare signext i32 @foo(...)374 375declare ptr addrspace(1) @domalloc(i64)376