Commit 56a34e3e by Martin Jambor

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

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.

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.

(cherry picked from commit b9a15a8325ba89b926e3c437b7961829a6b2fa2b)
parent 2c10856d
...@@ -3271,7 +3271,9 @@ all_callee_accesses_present_p (isra_param_desc *param_desc, ...@@ -3271,7 +3271,9 @@ all_callee_accesses_present_p (isra_param_desc *param_desc,
continue; continue;
param_access *pacc = find_param_access (param_desc, argacc->unit_offset, param_access *pacc = find_param_access (param_desc, argacc->unit_offset,
argacc->unit_size); argacc->unit_size);
if (!pacc || !pacc->certain) if (!pacc
|| !pacc->certain
|| !types_compatible_p (argacc->type, pacc->type))
return false; return false;
} }
return true; return true;
......
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment