diff --git a/gcc.spec b/gcc.spec index 5e68f3b8b75897b5e3d55b99f1352134ffeff77f..d0900e19a3634433cc4e86db40ad4d39e9e4fe29 100644 --- a/gcc.spec +++ b/gcc.spec @@ -1,4 +1,4 @@ -%define anolis_release 5 +%define anolis_release 6 %global DATE 20221121 %global gitrev b3f5a0d53b84ed27cf00cfa2b9c3e2c78935c07d @@ -249,6 +249,7 @@ Patch3128: LoongArch-Add-LA664-support.patch Patch3129: LoongArch-Fix-internal-error-running-gcc-march-nativ.patch Patch3130: LoongArch-Fix-lsx-vshuf.c-and-lasx-xvshuf_b.c-tests-.patch Patch3131: LoongArch-Fix-osdirname.patch +Patch3132: tree-optimization-110702-avoid-zero-based-memory-ref.patch # Part 5000 ~ 5999 Patch5001: HYGON-0001-arch-support-for-hygon.patch @@ -901,6 +902,7 @@ The %{name}-doc package contains documentation files for %{name}. %patch3129 -p1 %patch3130 -p1 %patch3131 -p1 +%patch3132 -p1 %endif %ifarch x86_64 %patch5001 -p1 @@ -2369,6 +2371,9 @@ end %changelog +* Mon Sep 23 2024 Peng Fan 12.3.0-6 +- LoongArch: avoid zero-based memory references in IVOPTs. + * Thu Jun 13 2024 Peng Fan 12.3.0-5 - LoongArch: fix osdir name. diff --git a/tree-optimization-110702-avoid-zero-based-memory-ref.patch b/tree-optimization-110702-avoid-zero-based-memory-ref.patch new file mode 100644 index 0000000000000000000000000000000000000000..0bd0fe249b635458cbffa724da5759edb6c92843 --- /dev/null +++ b/tree-optimization-110702-avoid-zero-based-memory-ref.patch @@ -0,0 +1,119 @@ +From 13dfb01e5c30c3bd09333ac79d6ff96a617fea67 Mon Sep 17 00:00:00 2001 +From: Richard Biener +Date: Thu, 3 Aug 2023 13:11:12 +0200 +Subject: [PATCH] tree-optimization/110702 - avoid zero-based memory references + in IVOPTs + +Sometimes IVOPTs chooses a weird induction variable which downstream +leads to issues. Most of the times we can fend those off during costing +by rejecting the candidate but it looks like the address description +costing synthesizes is different from what we end up generating so +the following fixes things up at code generation time. Specifically +we avoid the create_mem_ref_raw fallback which uses a literal zero +address base with the actual base in index2. For the case in question +we have the address + + type = unsigned long + offset = 0 + elements = { + [0] = &e * -3, + [1] = (sizetype) a.9_30 * 232, + [2] = ivtmp.28_44 * 4 + } + +from which we code generate the problematical + + _3 = MEM[(long int *)0B + ivtmp.36_9 + ivtmp.28_44 * 4]; + +which references the object at address zero. The patch below +recognizes the fallback after the fact and transforms the +TARGET_MEM_REF memory reference into a LEA for which this form +isn't problematic: + + _24 = &MEM[(long int *)0B + ivtmp.36_34 + ivtmp.28_44 * 4]; + _3 = *_24; + +hereby avoiding the correctness issue. We'd later conclude the +program terminates at the null pointer dereference and make the +function pure, miscompling the main function of the testcase. + + PR tree-optimization/110702 + * tree-ssa-loop-ivopts.cc (rewrite_use_address): When + we created a NULL pointer based access rewrite that to + a LEA. + + * gcc.dg/torture/pr110702.c: New testcase. +--- + gcc/testsuite/gcc.dg/torture/pr110702.c | 31 +++++++++++++++++++++++++ + gcc/tree-ssa-loop-ivopts.cc | 17 +++++++++++++- + 2 files changed, 47 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.dg/torture/pr110702.c + +diff --git a/gcc/testsuite/gcc.dg/torture/pr110702.c b/gcc/testsuite/gcc.dg/torture/pr110702.c +new file mode 100644 +index 00000000000..aab9c7d923e +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/torture/pr110702.c +@@ -0,0 +1,31 @@ ++/* { dg-do run } */ ++ ++void abort (void); ++ ++int a, b, c, d; ++long e[9][7][4]; ++ ++void f() ++{ ++ for (; a >= 0; a--) ++ { ++ b = 0; ++ for (; b <= 3; b++) ++ { ++ c = 0; ++ for (; c <= 3; c++) ++ { ++ int *g = &d; ++ *g = e[0][0][b] | e[a][b][a]; ++ } ++ } ++ } ++} ++ ++int main() ++{ ++ f(); ++ if (a != -1) ++ abort (); ++ return 0; ++} +diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc +index 92fc1c7d734..934897af691 100644 +--- a/gcc/tree-ssa-loop-ivopts.cc ++++ b/gcc/tree-ssa-loop-ivopts.cc +@@ -7630,7 +7630,22 @@ rewrite_use_address (struct ivopts_data *data, + true, GSI_SAME_STMT); + } + else +- copy_ref_info (ref, *use->op_p); ++ { ++ /* When we end up confused enough and have no suitable base but ++ stuffed everything to index2 use a LEA for the address and ++ create a plain MEM_REF to avoid basing a memory reference ++ on address zero which create_mem_ref_raw does as fallback. */ ++ if (TREE_CODE (ref) == TARGET_MEM_REF ++ && TMR_INDEX2 (ref) != NULL_TREE ++ && integer_zerop (TREE_OPERAND (ref, 0))) ++ { ++ ref = fold_build1 (ADDR_EXPR, TREE_TYPE (TREE_OPERAND (ref, 0)), ref); ++ ref = force_gimple_operand_gsi (&bsi, ref, true, NULL_TREE, ++ true, GSI_SAME_STMT); ++ ref = build2 (MEM_REF, type, ref, build_zero_cst (alias_ptr_type)); ++ } ++ copy_ref_info (ref, *use->op_p); ++ } + + *use->op_p = ref; + } +-- +2.33.0 +