This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch RFC IA64] Fixing predication & autoinc interaction
On Tue, 29 Sep 2009, Paolo Bonzini wrote:
On 09/29/2009 01:25 AM, Bernd Schmidt wrote:
since if_then_else is not handled
specially anywhere in the compiler, or documented to have special
semantics, I think the default assumption has to be that it behaves like
any other RTL code. So, I'm with Mike here.
I agree (to be precise, it's actually Richard Earnshaw speaking in
http://gcc.gnu.org/ml/gcc/2000-01/msg00394.html while Michael advocated
special semantics). In particular Richard mentions how reload can move
sub-expressions out of the insn and this will break if if_then_else has
special semantics.
I think that, given this, Steve's MD patch is much better.
I see. Thanks for the explanation.
However, following the ARM approach, we probably want to disallow side
effects only for IF_THEN_ELSE forms and leave "predicable" attributes on
everything, since they produce COND_EXEC forms of conditional assignment.
I think the following part of Steve's original patch should be sufficient
(bootstrapping it now):
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index f9c6de2..6e55cce 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -4083,16 +4083,16 @@
;;
(define_insn "*cmovdi_internal"
- [(set (match_operand:DI 0 "destination_operand"
+ [(set (match_operand:DI 0 "not_postinc_destination_operand"
"= r, r, r, r, r, r, r, r, r, r, m, Q, *f,*b,*d*e")
(if_then_else:DI
(match_operator 4 "predicate_operator"
[(match_operand:BI 1 "register_operand"
"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
(const_int 0)])
- (match_operand:DI 2 "move_operand"
+ (match_operand:DI 2 "not_postinc_move_operand"
"rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO, rK")
- (match_operand:DI 3 "move_operand"
+ (match_operand:DI 3 "not_postinc_move_operand"
"rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))]
"ia64_move_ok (operands[0], operands[2])
&& ia64_move_ok (operands[0], operands[3])"
@@ -4100,13 +4100,13 @@
[(set_attr "predicable" "no")])
(define_split
- [(set (match_operand 0 "destination_operand" "")
+ [(set (match_operand 0 "not_postinc_destination_operand" "")
(if_then_else
(match_operator 4 "predicate_operator"
[(match_operand:BI 1 "register_operand" "")
(const_int 0)])
- (match_operand 2 "move_operand" "")
- (match_operand 3 "move_operand" "")))]
+ (match_operand 2 "not_postinc_move_operand" "")
+ (match_operand 3 "not_postinc_move_operand" "")))]
"reload_completed"
[(const_int 0)]
{
@@ -4188,14 +4188,14 @@
;;
(define_insn "*cmovsi_internal"
- [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
+ [(set (match_operand:SI 0 "not_postinc_destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
(if_then_else:SI
(match_operator 4 "predicate_operator"
[(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
(const_int 0)])
- (match_operand:SI 2 "move_operand"
+ (match_operand:SI 2 "not_postinc_move_operand"
"0,0,0,rim*f,rO,rO,rim*f,rO,rO")
- (match_operand:SI 3 "move_operand"
+ (match_operand:SI 3 "not_postinc_move_operand"
"rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
"ia64_move_ok (operands[0], operands[2])
&& ia64_move_ok (operands[0], operands[3])"
diff --git a/gcc/config/ia64/predicates.md b/gcc/config/ia64/predicates.md
index 1503a05..2d0af6f 100644
--- a/gcc/config/ia64/predicates.md
+++ b/gcc/config/ia64/predicates.md
@@ -281,6 +281,12 @@
|| GET_CODE (XEXP (op, 0)) != POST_MODIFY
|| GET_CODE (XEXP (XEXP (XEXP (op, 0), 1), 1)) != REG")))
+;; Like destination_operand, but don't allow any post-increments.
+(define_predicate "not_postinc_destination_operand"
+ (and (match_operand 0 "nonimmediate_operand")
+ (match_test "GET_CODE (op) != MEM
+ || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
;; Like memory_operand, but don't allow post-increments.
(define_predicate "not_postinc_memory_operand"
(and (match_operand 0 "memory_operand")
@@ -332,6 +338,12 @@
}
})
+;; Like move_operand but don't allow post-increments.
+(define_predicate "not_postinc_move_operand"
+ (and (match_operand 0 "move_operand")
+ (match_test "GET_CODE (op) != MEM
+ || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
;; True if OP is a register operand that is (or could be) a GR reg.
(define_predicate "gr_register_operand"
(match_operand 0 "register_operand")