The following patch fixes two GCC testsuite failures for LRA. The patch
makes swap through registers instead of memory for the test cases when
LRA is used.
There are differences in reload and LRA constraint matching algorithm
which results in different alternative choices when the original pattern
is used.
Actually my first proposed solution variant used one pattern which is
now for LRA in this patch. But some doubt arose that it may affect
reload pass in some bad way.
Ok to commit?
2013-12-05 Vladimir Makarov <vmaka...@redhat.com>
* config/rs6000/rs6000.md (*bswapdi2_64bit): Make two versions of
the insn definition. One is for reload, another one is for LRA.
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 205647)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -2377,14 +2377,28 @@
[(set_attr "length" "4,4,36")
(set_attr "type" "load,store,*")])
-;; Non-power7/cell, fall back to use lwbrx/stwbrx
+;; Non-power7/cell, fall back to use lwbrx/stwbrx -- reload variant
(define_insn "*bswapdi2_64bit"
[(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
(clobber (match_scratch:DI 2 "=&b,&b,&r"))
(clobber (match_scratch:DI 3 "=&r,&r,&r"))
(clobber (match_scratch:DI 4 "=&r,X,&r"))]
- "TARGET_POWERPC64 && !TARGET_LDBRX
+ "TARGET_POWERPC64 && !TARGET_LDBRX && !rs6000_lra_flag
+ && (REG_P (operands[0]) || REG_P (operands[1]))
+ && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
+ && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
+ "#"
+ [(set_attr "length" "16,12,36")])
+
+;; Non-power7/cell, fall back to use lwbrx/stwbrx -- LRA variant
+(define_insn "*bswapdi2_64bit"
+ [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r")
+ (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
+ (clobber (match_scratch:DI 2 "=&b,&b,&r"))
+ (clobber (match_scratch:DI 3 "=&r,&r,&r"))
+ (clobber (match_scratch:DI 4 "=&r,X,&r"))]
+ "TARGET_POWERPC64 && !TARGET_LDBRX && rs6000_lra_flag
&& (REG_P (operands[0]) || REG_P (operands[1]))
&& !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
&& !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"