ipa-sra: Avoid transitive splits with type mismatches (PR 96040)

Message ID ri6v9j4wqrs.fsf@suse.cz
State New
Headers show
Series
  • ipa-sra: Avoid transitive splits with type mismatches (PR 96040)
Related show

Commit Message

Martin Jambor July 3, 2020, 3:40 p.m.
Hi,

PR 96040 revealed IPA-SRA, when checking whether an intended split is
the same as the one in a called function does not also check if the
types match and the transformation code does not handle any resulting
type mismatches.  This patch simply avoids the the split in the case
of mismatches, so that we do not have to be careful about invalid
floating-point values being passed in floating point registers and
related issues.

Bootstrapped and tested on x86_64-linux, pre-approved by Richi on IRC, I
will push it to master in a moment and to the gcc-10 branch immediately
after bootstrap on top of it finishes.

Thanks,


Martin


gcc/ChangeLog:

2020-07-03  Martin Jambor  <mjambor@suse.cz>

	PR ipa/96040
	* ipa-sra.c (all_callee_accesses_present_p): Do not accept type
	mismatched accesses.

gcc/testsuite/ChangeLog:

2020-07-03  Martin Jambor  <mjambor@suse.cz>

	PR ipa/96040
	* gcc.dg/ipa/pr96040.c: New test.
---
 gcc/ipa-sra.c                      |  4 ++-
 gcc/testsuite/gcc.dg/ipa/pr96040.c | 57 ++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/pr96040.c

-- 
2.27.0

Patch

diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c
index c81e8869e7a..03e3fc55daf 100644
--- a/gcc/ipa-sra.c
+++ b/gcc/ipa-sra.c
@@ -3271,7 +3271,9 @@  all_callee_accesses_present_p (isra_param_desc *param_desc,
 	continue;
       param_access *pacc = find_param_access (param_desc, argacc->unit_offset,
 					      argacc->unit_size);
-      if (!pacc || !pacc->certain)
+      if (!pacc
+	  || !pacc->certain
+	  || !types_compatible_p (argacc->type, pacc->type))
 	return false;
     }
   return true;
diff --git a/gcc/testsuite/gcc.dg/ipa/pr96040.c b/gcc/testsuite/gcc.dg/ipa/pr96040.c
new file mode 100644
index 00000000000..af7e9c4ed94
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr96040.c
@@ -0,0 +1,57 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -std=c99" } */
+
+
+int puts(const char *);
+int snprintf(char *, unsigned long, const char *, ...);
+unsigned long strspn(const char *, const char *);
+
+struct TValue {
+  union {
+    long long i;
+    double n;
+  } value_;
+  unsigned char tt_;
+};
+
+static int tostringbuff (struct TValue *num, char *str) {
+  int len;
+  if (num->tt_ == 3) {
+    len = snprintf(str,50,"%lld",num->value_.i);
+  } else {
+    len = snprintf(str,50,"%.14g",num->value_.n);
+    if (str[strspn(str, "-0123456789")] == '\0') {
+      str[len++] = '.';
+      str[len++] = '0';
+    }
+  }
+  return len;
+}
+
+void unused (int *buff, struct TValue *num) {
+  char junk[50];
+  *buff += tostringbuff(num, junk);
+}
+
+char space[400];
+
+void addnum2buff (int *buff, struct TValue *num) __attribute__((__noinline__));
+void addnum2buff (int *buff, struct TValue *num) {
+  *buff += tostringbuff(num, space);
+}
+
+int __attribute__((noipa)) check_space (char *s)
+{
+  return (s[0] == '1' && s[1] == '.' && s[2] =='0' && s[3] == '\0');
+}
+
+int main(void) {
+    int buff = 0;
+    struct TValue num;
+    num.value_.n = 1.0;
+    num.tt_ = 19;
+    addnum2buff(&buff, &num);
+    if (!check_space(space))
+      __builtin_abort ();
+    return 0;
+}