This patch fixes the bug I mentioned in a previous patch, i.e.
#include <altivec.h>
static vector double v;
// ...
double foo (int n)
{
double x = vec_extract (v, n);
return x;
}
would generate incorrect code because it only has one temporary register, and
it needs two temporary registers (one to hold the pc-relative address, and the
other to hold the index). In the previous V3 patch #4 that added pc-relative
support, I put in an abort for this case. This patch actually fixes it.
Originally, I solved it by just adding a predicate/condition to not allow a
pc-relative address to combine with the extract directly. But I found the
reload pass was joining the two insns, so I added a new constraint (ep) to say
this memory insn must not involve a pc-relative address.
If you have an unused constraint pair that you would prefer instead of "ep", I
can easily switch to use that.
I built a boostrap compiler on a little endian power8 system, and there were no
regressions in running make check. Can I check this change into the trunk once
the previous patches are checked in?
2019-08-26 Michael Meissner <[email protected]>
* config/rs6000/constraints.md (ep constraint): New constraint.
* config/rs6000/predicates.md (non_pcrel_mem_operand): New
predicate.
(reg_or_non_pcrel_operand): New predicate.
* config/rs6000/vsx.md (vsx_extract_<mode>_var, VSX_D iterator):
Don't allow pc-relative memory addresses.
(vsx_extract_v4sf_var): Don't allow pc-relative memory addresses.
(vsx_extract_<mode>_var, VSX_EXTRACT_I iterator): Don't allow
pc-relative memory addresses.
(vsx_extract_<mode>_<VS_scalar>mode_var): Don't allow pc-relative
memory addresses.
* doc/md.texi (PowerPC Constraints): Document ep constraint.
Index: gcc/config/rs6000/constraints.md
===================================================================
--- gcc/config/rs6000/constraints.md (revision 274864)
+++ gcc/config/rs6000/constraints.md (working copy)
@@ -210,6 +210,11 @@ several times, or that might not access
(and (match_code "mem")
(match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+(define_memory_constraint "ep"
+ "A memory operand that does not contain a pc-relative reference."
+ (and (match_code "mem")
+ (match_test "non_pcrel_mem_operand (op, mode)")))
+
(define_memory_constraint "Q"
"Memory operand that is an offset from a register (it is usually better
to use @samp{m} or @samp{es} in @code{asm} statements)"
Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md (revision 274874)
+++ gcc/config/rs6000/predicates.md (working copy)
@@ -1706,6 +1706,33 @@ (define_predicate "non_prefixed_mem_oper
TRAD_INSN_DEFAULT);
})
+;; Return 1 if op is a memory operand that does not contain a pc-relative
+;; address.
+(define_predicate "non_pcrel_mem_operand"
+ (match_code "mem")
+{
+ if (!memory_operand (op, mode))
+ return false;
+
+ return (!pcrel_local_address (XEXP (op, 0), Pmode)
+ && !pcrel_ext_address (XEXP (op, 0), Pmode));
+})
+
+;; Return 1 if op is a register or a memory operand that does not contain a
+;; pc-relatve address.
+(define_predicate "reg_or_non_pcrel_operand"
+ (match_code "reg,subreg,mem")
+{
+ if (REG_P (op) || SUBREG_P (op))
+ return true;
+
+ if (!memory_operand (op, mode))
+ return false;
+
+ return (!pcrel_local_address (XEXP (op, 0), Pmode)
+ && !pcrel_ext_address (XEXP (op, 0), Pmode));
+})
+
;; Match the first insn (addis) in fusing the combination of addis and loads to
;; GPR registers on power8.
(define_predicate "fusion_gpr_addis"
Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md (revision 274874)
+++ gcc/config/rs6000/vsx.md (working copy)
@@ -3249,9 +3249,10 @@ (define_insn "vsx_vslo_<mode>"
;; Variable V2DI/V2DF extract
(define_insn_and_split "vsx_extract_<mode>_var"
[(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=v,wa,r")
- (unspec:<VS_scalar> [(match_operand:VSX_D 1 "input_operand" "v,m,m")
- (match_operand:DI 2 "gpc_reg_operand" "r,r,r")]
- UNSPEC_VSX_EXTRACT))
+ (unspec:<VS_scalar>
+ [(match_operand:VSX_D 1 "reg_or_non_pcrel_operand" "v,ep,ep")
+ (match_operand:DI 2 "gpc_reg_operand" "r,r,r")]
+ UNSPEC_VSX_EXTRACT))
(clobber (match_scratch:DI 3 "=r,&b,&b"))
(clobber (match_scratch:V2DI 4 "=&v,X,X"))]
"VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT"
@@ -3319,9 +3320,10 @@ (define_insn_and_split "*vsx_extract_v4s
;; Variable V4SF extract
(define_insn_and_split "vsx_extract_v4sf_var"
[(set (match_operand:SF 0 "gpc_reg_operand" "=wa,wa,?r")
- (unspec:SF [(match_operand:V4SF 1 "input_operand" "v,m,m")
- (match_operand:DI 2 "gpc_reg_operand" "r,r,r")]
- UNSPEC_VSX_EXTRACT))
+ (unspec:SF
+ [(match_operand:V4SF 1 "reg_or_non_pcrel_operand" "v,ep,ep")
+ (match_operand:DI 2 "gpc_reg_operand" "r,r,r")]
+ UNSPEC_VSX_EXTRACT))
(clobber (match_scratch:DI 3 "=r,&b,&b"))
(clobber (match_scratch:V2DI 4 "=&v,X,X"))]
"VECTOR_MEM_VSX_P (V4SFmode) && TARGET_DIRECT_MOVE_64BIT"
@@ -3682,7 +3684,7 @@ (define_insn_and_split "*vsx_extract_<mo
(define_insn_and_split "vsx_extract_<mode>_var"
[(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=r,r,r")
(unspec:<VS_scalar>
- [(match_operand:VSX_EXTRACT_I 1 "input_operand" "v,v,m")
+ [(match_operand:VSX_EXTRACT_I 1 "reg_or_non_pcrel_operand" "v,v,ep")
(match_operand:DI 2 "gpc_reg_operand" "r,r,r")]
UNSPEC_VSX_EXTRACT))
(clobber (match_scratch:DI 3 "=r,r,&b"))
@@ -3702,7 +3704,7 @@ (define_insn_and_split "*vsx_extract_<mo
[(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=r,r,r")
(zero_extend:<VS_scalar>
(unspec:<VSX_EXTRACT_I:VS_scalar>
- [(match_operand:VSX_EXTRACT_I 1 "input_operand" "v,v,m")
+ [(match_operand:VSX_EXTRACT_I 1 "reg_or_non_pcrel_operand" "v,v,ep")
(match_operand:DI 2 "gpc_reg_operand" "r,r,r")]
UNSPEC_VSX_EXTRACT)))
(clobber (match_scratch:DI 3 "=r,r,&b"))
Index: gcc/doc/md.texi
===================================================================
--- gcc/doc/md.texi (revision 274864)
+++ gcc/doc/md.texi (working copy)
@@ -3343,6 +3343,9 @@ Constant whose negation is a signed 16-b
@item eI
Signed 34-bit integer constant if prefixed instructions are supported.
+@item ep
+A memory operand that does not include a pc-relative address.
+
@item G
Floating point constant that can be loaded into a register with one
instruction per word
--
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: [email protected], phone: +1 (978) 899-4797