21 Star 27 Fork 151

src-openEuler/gcc

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0190-tree-optimization-110702-avoid-zero-based-memory-ref.patch 3.47 KB
一键复制 编辑 原始数据 按行查看 历史
ticat_fp 提交于 2024-10-31 10:33 +08:00 . LoongArch: Sync to upstream
From 13dfb01e5c30c3bd09333ac79d6ff96a617fea67 Mon Sep 17 00:00:00 2001
From: Richard Biener <rguenther@suse.de>
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.45.2
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/src-openeuler/gcc.git
git@gitee.com:src-openeuler/gcc.git
src-openeuler
gcc
gcc
master

搜索帮助