diff --git a/21-add-align-prgma-for-fix-shape-array-character-type.patch b/21-add-align-prgma-for-fix-shape-array-character-type.patch new file mode 100644 index 0000000000000000000000000000000000000000..0f60c382fc63fa216ab1a47e285e6475ddc58d15 --- /dev/null +++ b/21-add-align-prgma-for-fix-shape-array-character-type.patch @@ -0,0 +1,468 @@ +From 4ff3f25edbc9fe18b159b121e3323c1ec68bdc52 Mon Sep 17 00:00:00 2001 +From: yinjiawei2023 +Date: Thu, 1 Jun 2023 22:50:53 +0800 +Subject: [PATCH] [flang] Add align pragma for fix shape array/character + +This patch add align pragma for fix shape array/character, +and add some test cases for this pragma. +--- + test/directives/align_array_type.f90 | 157 +++++++++++++++++++++++ + test/directives/align_character_type.f90 | 111 ++++++++++++++++ + tools/flang1/flang1exe/dtypeutl.c | 7 +- + tools/flang1/flang1exe/exterf.c | 18 +++ + tools/flang1/flang1exe/interf.c | 2 + + tools/flang1/flang1exe/lowersym.c | 18 +++ + tools/flang2/flang2exe/dtypeutl.cpp | 7 +- + tools/flang2/flang2exe/upper.cpp | 5 +- + 8 files changed, 322 insertions(+), 3 deletions(-) + create mode 100644 test/directives/align_array_type.f90 + create mode 100644 test/directives/align_character_type.f90 + +diff --git a/test/directives/align_array_type.f90 b/test/directives/align_array_type.f90 +new file mode 100644 +index 0000000..5335a9b +--- /dev/null ++++ b/test/directives/align_array_type.f90 +@@ -0,0 +1,157 @@ ++! RUN: %flang -O0 -S -emit-llvm %s -o - | FileCheck %s ++ ++! CHECK: %struct[[BLOCK1:\.BSS[0-9]+]] = type <{ [356 x i8] }> ++! CHECK: %struct[[BLOCK2:\.BSS[0-9]+]] = type <{ [612 x i8] }> ++! CHECK: %struct[[BLOCK3:\.BSS[0-9]+]] = type <{ [1124 x i8] }> ++! CHECK: %struct[[BLOCK4:\.BSS[0-9]+]] = type <{ [2148 x i8] }> ++! CHECK: %struct[[BLOCK5:_module_align_array_[0-9]+_]] = type <{ [228 x i8] }> ++! CHECK: @[[BLOCK1]] = internal global %struct[[BLOCK1]] zeroinitializer, align 256 ++! CHECK: @[[BLOCK2]] = internal global %struct[[BLOCK2]] zeroinitializer, align 512 ++! CHECK: @[[BLOCK3]] = internal global %struct[[BLOCK3]] zeroinitializer, align 1024 ++! CHECK: @[[BLOCK4]] = internal global %struct[[BLOCK4]] zeroinitializer, align 2048 ++! CHECK: @[[BLOCK5]] = common global %struct[[BLOCK5]] zeroinitializer, align 128 ++ ++module module_align_array ++implicit none ++ ++ !dir$ align 128 ++ integer, dimension (5,5) :: v1 ++ ++ !dir$ align 128 ++ integer, dimension (5,5) :: v2 ++ ++ interface ++ module subroutine module_interface_subroutine() ++ end subroutine module_interface_subroutine ++ end interface ++ ++end module module_align_array ++ ++submodule (module_align_array) submodule_align_array ++ ++ contains ++ module subroutine module_interface_subroutine() ++ ++ !dir$ align 256 ++ integer, dimension (5,5) :: v3 ++ ++ !dir$ align 256 ++ integer, dimension (5,5) :: v4 ++ ++ ++ v3(1, 1) = 101 ++! CHECK: store i32 101, ptr @[[BLOCK1]], align ++ ++ v3(5, 5) = 102 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK1]], i64 96 ++! CHECK: store i32 102, ptr %[[TEMP]], align ++ ++ v4(1, 1) = 103 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK1]], i64 256 ++! CHECK: store i32 103, ptr %[[TEMP]], align ++ ++ v4(5, 5) = 104 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK1]], i64 352 ++! CHECK: store i32 104, ptr %[[TEMP]], align ++ ++ end subroutine module_interface_subroutine ++end submodule submodule_align_array ++ ++ ++ ++program align ++use module_align_array ++implicit none ++ ++ !dir$ align 512 ++ integer, dimension (5,5) :: v5 ++ ++ !dir$ align 512 ++ integer, dimension (5,5) :: v6 ++ ++ ++ v5(1, 1) = 201 ++! CHECK: store i32 201, ptr @[[BLOCK2]], align ++ ++ v5(5, 5) = 202 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK2]], i64 96 ++! CHECK: store i32 202, ptr %[[TEMP]], align ++ ++ v6(1, 1) = 203 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK2]], i64 512 ++! CHECK: store i32 203, ptr %[[TEMP]], align ++ ++ v6(5, 5) = 204 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK2]], i64 608 ++! CHECK: store i32 204, ptr %[[TEMP]], align ++ ++ v1(1, 1) = 81 ++! CHECK: store i32 81, ptr @[[BLOCK5]], align ++ ++ v1(5, 5) = 82 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK5]], i64 96 ++! CHECK: store i32 82, ptr %[[TEMP]], align ++ ++ v2(1, 1) = 83 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK5]], i64 128 ++! CHECK: store i32 83, ptr %[[TEMP]], align ++ ++ v2(5, 5) = 84 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK5]], i64 224 ++! CHECK: store i32 84, ptr %[[TEMP]], align ++ ++end program align ++ ++ ++subroutine subroutine_align() ++ ++ !dir$ align 1024 ++ integer, dimension (5,5) :: v7 ++ ++ !dir$ align 1024 ++ integer, dimension (5,5) :: v8 ++ ++ v7(1, 1) = 401 ++! CHECK: store i32 401, ptr @[[BLOCK3]], align ++ ++ v7(5, 5) = 402 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK3]], i64 96 ++! CHECK: store i32 402, ptr %[[TEMP]], align ++ ++ v8(1, 1) = 403 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK3]], i64 1024 ++! CHECK: store i32 403, ptr %[[TEMP]], align ++ ++ v8(5, 5) = 404 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK3]], i64 1120 ++! CHECK: store i32 404, ptr %[[TEMP]], align ++ ++ return ++end subroutine subroutine_align ++ ++ ++function function_align() ++ ++ !dir$ align 2048 ++ integer, dimension (5,5) :: v9 ++ ++ !dir$ align 2048 ++ integer, dimension (5,5) :: v10 ++ ++ v9(1, 1) = 801 ++! CHECK: store i32 801, ptr @[[BLOCK4]], align ++ ++ v9(5, 5) = 802 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK4]], i64 96 ++! CHECK: store i32 802, ptr %[[TEMP]], align ++ ++ v10(1, 1) = 803 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK4]], i64 2048 ++! CHECK: store i32 803, ptr %[[TEMP]], align ++ ++ v10(5, 5) = 804 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK4]], i64 2144 ++! CHECK: store i32 804, ptr %[[TEMP]], align ++ ++ return ++end function function_align +diff --git a/test/directives/align_character_type.f90 b/test/directives/align_character_type.f90 +new file mode 100644 +index 0000000..adc96c6 +--- /dev/null ++++ b/test/directives/align_character_type.f90 +@@ -0,0 +1,111 @@ ++! RUN: %flang -O0 -S -emit-llvm %s -o - | FileCheck %s ++ ++! CHECK: %struct[[BLOCK1:_module_align_character_[0-9]+_]] = type <{ [138 x i8] } ++! CHECK: @[[BLOCK1]] = common global %struct[[BLOCK1]] zeroinitializer, align 512 ++ ++module module_align_character ++implicit none ++ ++ !dir$ align 128 ++ character(len=10) :: v1 ++ ++ !dir$ align 128 ++ character(len=10) :: v2 ++ ++ interface ++ module subroutine module_interface_subroutine() ++ end subroutine module_interface_subroutine ++ end interface ++ ++end module module_align_character ++ ++submodule (module_align_character) submodule_align_character ++ ++ contains ++ module subroutine module_interface_subroutine() ++ ++ !dir$ align 256 ++ character(len=10) :: v3 ++! CHECK: %[[V3:v3_[0-9]+]] = alloca [10 x i8], align 256 ++ ++ !dir$ align 256 ++ character(len=10) :: v4 ++! CHECK: %[[V4:v4_[0-9]+]] = alloca [10 x i8], align 256 ++ ++ v3 = "101" ++! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V3]], align ++ ++ v4 = "102" ++! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V4]], align ++ ++ end subroutine module_interface_subroutine ++end submodule submodule_align_character ++ ++ ++ ++program align ++use module_align_character ++implicit none ++ ++ !dir$ align 512 ++ character(len=10) :: v5 ++! CHECK: %[[V5:v5_[0-9]+]] = alloca [10 x i8], align 512 ++ ++ !dir$ align 512 ++ character(len=10) :: v6 ++! CHECK: %[[V6:v6_[0-9]+]] = alloca [10 x i8], align 512 ++ ++ v5 = "201" ++! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V5]], align ++ ++ v6 = "202" ++! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V6]], align ++ ++ v1 = "81" ++! CHECK: store volatile i64 %{{[0-9]+}}, ptr @[[BLOCK1]], align ++ ++ v2 = "82" ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK1]], i64 512 ++! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[TEMP]], align ++ ++end program align ++ ++ ++subroutine subroutine_align() ++ ++ !dir$ align 1024 ++ character(len=10) :: v7 ++! CHECK: %[[V7:v7_[0-9]+]] = alloca [10 x i8], align 1024 ++ ++ !dir$ align 1024 ++ character(len=10) :: v8 ++! CHECK: %[[V8:v8_[0-9]+]] = alloca [10 x i8], align 1024 ++ ++ v7 = "401" ++! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V7]], align ++ ++ v8 = "402" ++! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V8]], align ++ ++ return ++end subroutine subroutine_align ++ ++ ++function function_align() ++ ++ !dir$ align 2048 ++ character(len=10) :: v9 ++! CHECK: %[[V9:v9_[0-9]+]] = alloca [10 x i8], align 2048 ++ ++ !dir$ align 2048 ++ character(len=10) :: v10 ++! CHECK: %[[V10:v10_[0-9]+]] = alloca [10 x i8], align 2048 ++ ++ v9 = "801" ++! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V9]], align ++ ++ v10 = "802" ++! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V10]], align ++ ++ return ++end function function_align +diff --git a/tools/flang1/flang1exe/dtypeutl.c b/tools/flang1/flang1exe/dtypeutl.c +index 33fa5bc..fa280d9 100644 +--- a/tools/flang1/flang1exe/dtypeutl.c ++++ b/tools/flang1/flang1exe/dtypeutl.c +@@ -1213,7 +1213,10 @@ alignment(DTYPE dtype) + case TY_CHAR: + case TY_NCHAR: + case TY_PTR: +- return dtypeinfo[ty].align; ++ align_val = dtypeinfo[ty].align; ++ if (DTA(dtype) > align_val) ++ return DTA(dtype); ++ return align_val; + case TY_INT8: + case TY_LOG8: + if (!flg.dalign || XBIT(119, 0x100000)) +@@ -1222,6 +1225,8 @@ alignment(DTYPE dtype) + + case TY_ARRAY: + align_val = alignment((int)DTY(dtype + 1)); ++ if (DTA(dtype) > align_val) ++ return DTA(dtype); + return align_val; + + case TY_STRUCT: +diff --git a/tools/flang1/flang1exe/exterf.c b/tools/flang1/flang1exe/exterf.c +index 51f412d..21e8444 100644 +--- a/tools/flang1/flang1exe/exterf.c ++++ b/tools/flang1/flang1exe/exterf.c +@@ -2104,6 +2104,15 @@ export_dt(int dtype) + } + } else /* 'null' descriptor */ + lzprintf(outlz, " %d", 0); ++ ++ /* If align pragma value is smaller than its original alignment, ++ * then align pragma should have no effect ++ */ ++ if (DTA(dtype) == alignment(dtype)) ++ lzprintf(outlz, " %d", (int)DTA(dtype)); ++ else ++ lzprintf(outlz, " %d", 0); ++ + break; + case TY_UNION: + case TY_STRUCT: +@@ -2120,6 +2129,15 @@ export_dt(int dtype) + case TY_CHAR: + case TY_NCHAR: + lzprintf(outlz, " %d", (int)DTY(dtype + 1)); ++ ++ /* If align pragma value is smaller than its original alignment, ++ * then align pragma should have no effect ++ */ ++ if (DTA(dtype) == alignment(dtype)) ++ lzprintf(outlz, " %d", (int)DTA(dtype)); ++ else ++ lzprintf(outlz, " %d", 0); ++ + break; + + case TY_PROC: +diff --git a/tools/flang1/flang1exe/interf.c b/tools/flang1/flang1exe/interf.c +index ac77826..39dde48 100644 +--- a/tools/flang1/flang1exe/interf.c ++++ b/tools/flang1/flang1exe/interf.c +@@ -2160,6 +2160,7 @@ import(lzhandle *fdlz, WantPrivates wantPrivates, int ivsn) + ADD_EXTNTAST(new_id, i) = get_num(10); + } + } ++ DTA(new_id) = get_num(10); /* align */ + break; + case TY_UNION: + case TY_STRUCT: +@@ -2176,6 +2177,7 @@ import(lzhandle *fdlz, WantPrivates wantPrivates, int ivsn) + case TY_NCHAR: + stringlen = get_num(10); + new_id = get_type(2, TY_NONE, stringlen); ++ DTA(new_id) = get_num(10); /* align */ + /* use TY_NONE to avoid 'sharing' character data types */ + DTY(new_id) = pd->ty; + break; +diff --git a/tools/flang1/flang1exe/lowersym.c b/tools/flang1/flang1exe/lowersym.c +index 87c22be..0285d1a 100644 +--- a/tools/flang1/flang1exe/lowersym.c ++++ b/tools/flang1/flang1exe/lowersym.c +@@ -2594,6 +2594,15 @@ lower_put_datatype(int dtype, int usage) + } + } + } ++ ++ /* If align pragma value is smaller than its original alignment, ++ * then align pragma should have no effect ++ */ ++ if (DTA(dtype) == alignment(dtype)) ++ putval("align", DTA(dtype)); ++ else ++ putval("align", 0); ++ + break; + case TY_NCHAR: + putwhich("kcharacter", "k"); +@@ -2955,6 +2964,15 @@ lower_put_datatype(int dtype, int usage) + } + } + putsym("numelm", numelm); ++ ++ /* If align pragma value is smaller than its original alignment, ++ * then align pragma should have no effect ++ */ ++ if (DTA(dtype) == alignment(dtype)) ++ putval("align", DTA(dtype)); ++ else ++ putval("align", 0); ++ + break; + + default: +diff --git a/tools/flang2/flang2exe/dtypeutl.cpp b/tools/flang2/flang2exe/dtypeutl.cpp +index 46cd9f8..95c6af8 100644 +--- a/tools/flang2/flang2exe/dtypeutl.cpp ++++ b/tools/flang2/flang2exe/dtypeutl.cpp +@@ -488,7 +488,10 @@ alignment(DTYPE dtype) + case TY_LOG128: + case TY_FLOAT128: + case TY_CMPLX128: +- return dtypeinfo[ty].align; ++ align_bits = dtypeinfo[ty].align; ++ if (DTA(dtype) > align_bits) ++ return DTA(dtype); ++ return align_bits; + case TY_INT8: + case TY_UINT8: + case TY_LOG8: +@@ -498,6 +501,8 @@ alignment(DTYPE dtype) + + case TY_ARRAY: + align_bits = alignment(DTySeqTyElement(dtype)); ++ if (DTA(dtype) > align_bits) ++ return DTA(dtype); + return align_bits; + case TY_VECT: + return alignment(DTySeqTyElement(dtype)); +diff --git a/tools/flang2/flang2exe/upper.cpp b/tools/flang2/flang2exe/upper.cpp +index 664b868..7ddeeac 100644 +--- a/tools/flang2/flang2exe/upper.cpp ++++ b/tools/flang2/flang2exe/upper.cpp +@@ -1721,7 +1721,9 @@ read_datatype(void) + } else if (size == -4) { + datatypexref[dtype] = DT_DEFERCHAR; + } else { +- datatypexref[dtype] = get_type(2, dval, size); ++ dt = get_type(2, dval, size); ++ DTA(dt) = getval("align"); ++ datatypexref[dtype] = dt; + } + break; + case TY_NCHAR: +@@ -1754,6 +1756,7 @@ read_datatype(void) + } + AD_ZBASE(ad) = getval("zbase"); + AD_NUMELM(ad) = getSptrVal("numelm"); ++ DTA(dt) = getval("align"); + datatypexref[dtype] = dt; + break; + case TY_PTR: +-- +2.25.1 + diff --git a/flang.spec b/flang.spec index 80f860ef02738a3f34397dc7cf67f8207748a784..e8304d065abef9a4f502ca629454a46ff18c0a44 100644 --- a/flang.spec +++ b/flang.spec @@ -2,7 +2,7 @@ Name: flang Version: flang_20210324 -Release: 24 +Release: 25 Summary: Fortran language compiler targeting LLVM License: Apache-2.0 @@ -31,6 +31,7 @@ Patch16: 17-add-fortran-memory-align-investigation.patch Patch17: 18-add-test-cases-for-attribute-declarations-and-specifications-3.patch Patch18: 19-add-test-cases-for-types-3.patch Patch19: 20-add-align-prgma-for-derived-type.patch +Patch20: 21-add-align-prgma-for-fix-shape-array-character-type.patch %description Flang depends on a fork of the LLVM project (https://github.com/flang-compiler/classic-flang-llvm-project). The fork made some changes to the upstream LLVM project to support Flang toolchain. Flang cannot build independently for now. @@ -52,6 +53,9 @@ TODO: support build Flang. %changelog +* Fri May 19 2023 yinjiawei2023 - flang_20210324-25 +- Add patch for add align prgma for fix shape array/character and add some relative test cases + * Thu May 18 2023 yinjiawei2023 - flang_20210324-24 - Add patch for add align prgma for derived type and add some relative test cases