Skip to content

Commit 9f7ad76

Browse files
arc: check if the addend fits when referencing small data memory [PR115650]
This prevents linker errors when referencing small data using large offsets. In practice it is very unlikely to be a real problem but this was fixed because other compilers do this check and it ensures the following tests now succeed: - gcc.dg/torture/pr60115.c - gcc.dg/torture/pr105665.c PR target/115650 gcc/ChangeLog: * config/arc/arc.cc (legitimate_small_data_address_p): Check offset size. gcc/testsuite/ChangeLog: * gcc.target/arc/sdata-6.c: New test. Signed-off-by: Michiel Derhaeg <[email protected]>
1 parent b43dc7d commit 9f7ad76

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

gcc/config/arc/arc.cc

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -386,27 +386,35 @@ legitimate_small_data_address_p (rtx x, machine_mode mode)
386386
return SYMBOL_REF_SMALL_P (x);
387387
case PLUS:
388388
{
389-
bool p0 = (GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
390-
&& SYMBOL_REF_SMALL_P (XEXP (x, 0));
389+
if ((GET_CODE (XEXP (x, 0)) != SYMBOL_REF)
390+
|| !SYMBOL_REF_SMALL_P (XEXP (x, 0)))
391+
return false;
391392

392393
/* If no constant then we cannot do small data. */
393394
if (!CONST_INT_P (XEXP (x, 1)))
394395
return false;
395396

396-
/* Small data relocs works with scalled addresses, check if
397+
const int offset = INTVAL (XEXP (x, 1));
398+
int size = GET_MODE_SIZE (mode);
399+
size = size == 8 ? 4 : size;
400+
401+
/* Small data relocs works with scaled addresses, check if
397402
the immediate fits the requirements. */
398-
switch (GET_MODE_SIZE (mode))
403+
switch (size)
399404
{
400405
case 1:
401-
return p0;
406+
break;
402407
case 2:
403-
return p0 && ((INTVAL (XEXP (x, 1)) & 0x1) == 0);
408+
if ((offset & 0x1) == 0) break; else return false;
404409
case 4:
405-
case 8:
406-
return p0 && ((INTVAL (XEXP (x, 1)) & 0x3) == 0);
410+
if ((offset & 0x3) == 0) break; else return false;
407411
default:
408412
return false;
409413
}
414+
415+
/* Reloc allows scaled signed 9 bits. */
416+
const int v = (offset / size) >> 8;
417+
return v == 0 || v == -1;
410418
}
411419
default:
412420
return false;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-O2 -msdata" } */
3+
4+
__attribute__((section(".sdata"))) int a[300];
5+
6+
int f (void)
7+
{
8+
return a[255];
9+
}
10+
11+
int g (void)
12+
{
13+
return a[256];
14+
}
15+
16+
/* { dg-final { scan-assembler "ld_s\\s+r0,\\\[gp,@a@sda\\+1020\\\]" } } */
17+
/* { dg-final { scan-assembler "ld\\s+r0,\\\[@a\\+1024\\\]" } } */

0 commit comments

Comments
 (0)