From 5ec6aff2dd65faa0176b9cb4a32e2ebf707aa4da Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Sat, 4 May 2013 05:38:47 +0000 Subject: [PATCH] re PR target/57150 (GCC when targeting power7 spills long double using VSX instructions.) [gcc] 2013-05-03 Michael Meissner PR target/57150 * config/rs6000/rs6000.h (HARD_REGNO_CALLER_SAVE_MODE): Use DFmode to save TFmode registers and DImode to save TImode registers for caller save operations. (HARD_REGNO_CALL_PART_CLOBBERED): TFmode and TDmode do not need to mark being partially clobbered since they only use the first double word. * config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok): TFmode and TDmode only use the upper 64-bits of each VSX register. [gcc/testsuite] 2013-05-03 Michael Meissner PR target/57150 * gcc.target/powerpc/pr57150.c: New file. From-SVN: r198593 --- gcc/ChangeLog | 13 ++++++++++++ gcc/config/rs6000/rs6000.c | 12 +++++++++-- gcc/config/rs6000/rs6000.h | 14 +++++++++---- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/powerpc/pr57150.c | 23 ++++++++++++++++++++++ 5 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr57150.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2ff6d54c710..e91ea0027bb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2013-05-03 Michael Meissner + + PR target/57150 + * config/rs6000/rs6000.h (HARD_REGNO_CALLER_SAVE_MODE): Use DFmode + to save TFmode registers and DImode to save TImode registers for + caller save operations. + (HARD_REGNO_CALL_PART_CLOBBERED): TFmode and TDmode do not need to + mark being partially clobbered since they only use the first + double word. + + * config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok): TFmode + and TDmode only use the upper 64-bits of each VSX register. + 2013-05-03 Bill Schmidt * gimple-ssa-strength-reduction.c (slsr_process_phi): Disable. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 7c329754482..4f7fc70d566 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -2335,8 +2335,16 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) reg_size = UNITS_PER_WORD; for (m = 0; m < NUM_MACHINE_MODES; ++m) - rs6000_class_max_nregs[m][c] - = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size; + { + int reg_size2 = reg_size; + + /* TFmode/TDmode always takes 2 registers, even in VSX. */ + if (m == TDmode || m == TFmode) + reg_size2 = UNITS_PER_FP_WORD; + + rs6000_class_max_nregs[m][c] + = (GET_MODE_SIZE (m) + reg_size2 - 1) / reg_size2; + } } if (TARGET_E500_DOUBLE) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 2040db95b7f..6549347b9b7 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1071,12 +1071,17 @@ extern unsigned rs6000_pointer_size; #define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs[(MODE)][(REGNO)] /* When setting up caller-save slots (MODE == VOIDmode) ensure we allocate - enough space to account for vectors in FP regs. */ + enough space to account for vectors in FP regs. However, TFmode/TDmode + should not use VSX instructions to do a caller save. */ #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ (TARGET_VSX \ && ((MODE) == VOIDmode || ALTIVEC_OR_VSX_VECTOR_MODE (MODE)) \ - && FP_REGNO_P (REGNO) \ - ? V2DFmode \ + && FP_REGNO_P (REGNO) \ + ? V2DFmode \ + : ((MODE) == TFmode && FP_REGNO_P (REGNO)) \ + ? DFmode \ + : ((MODE) == TDmode && FP_REGNO_P (REGNO)) \ + ? DImode \ : choose_hard_reg_mode ((REGNO), (NREGS), false)) #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ @@ -1084,7 +1089,8 @@ extern unsigned rs6000_pointer_size; && (GET_MODE_SIZE (MODE) > 4) \ && INT_REGNO_P (REGNO)) ? 1 : 0) \ || (TARGET_VSX && FP_REGNO_P (REGNO) \ - && GET_MODE_SIZE (MODE) > 8)) + && GET_MODE_SIZE (MODE) > 8 && ((MODE) != TDmode) \ + && ((MODE) != TFmode))) #define VSX_VECTOR_MODE(MODE) \ ((MODE) == V4SFmode \ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bd5b01fc405..731ccd07c7d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-05-03 Michael Meissner + + PR target/57150 + * gcc.target/powerpc/pr57150.c: New file. + 2013-05-03 Bill Schmidt * gcc.dg/tree-ssa/slsr-32.c: Skip test for now. diff --git a/gcc/testsuite/gcc.target/powerpc/pr57150.c b/gcc/testsuite/gcc.target/powerpc/pr57150.c new file mode 100644 index 00000000000..119bc4c52fe --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr57150.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O3 -mcpu=power7 -fcaller-saves" } */ +/* { dg-final { scan-assembler-not "lxvd2x" } } */ +/* { dg-final { scan-assembler-not "lxvw4x" } } */ +/* { dg-final { scan-assembler-not "lvx" } } */ +/* { dg-final { scan-assembler-not "stxvd2x" } } */ +/* { dg-final { scan-assembler-not "stxvw4x" } } */ +/* { dg-final { scan-assembler-not "stvx" } } */ + +/* Insure caller save on long double does not use VSX instructions. */ + +extern long double modify (long double); + +void +sum (long double *ptr, long double value, unsigned long n) +{ + unsigned long i; + + for (i = 0; i < n; i++) + ptr[i] += modify (value); +}