https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95267

--- Comment #4 from otcmaf <xuemaosheng at huawei dot com> ---
(In reply to Andrew Pinski from comment #3)
> The internals documentation documents this even, read:
> https://gcc.gnu.org/onlinedocs/gccint/RTL-Template.html#index-match_005fdup
> 
> From that:
> Note that match_dup should not be used to tell the compiler that a
> particular register is being used for two operands (example: add that adds
> one register to another; the second register is both an input operand and
> the output operand). Use a matching constraint (see Simple Constraints) for
> those.

However, in gcc/config/aarch64/aarch64-simd.md also has the similar usage。
For example:
1227 (define_insn "aarch64_simd_move_hi_quad_<mode>"                            
1228   [(set (match_operand:VQ 0 "register_operand" "+w,w")                     
1229         (vec_concat:VQ                                                     
1230           (vec_select:<VHALF>                                              
1231                 (match_dup 0)                                              
1232                 (match_operand:VQ 2 "vect_par_cnst_lo_half" ""))           
1233           (match_operand:<VHALF> 1 "register_operand" "w,r")))]            
1234   "TARGET_SIMD && !BYTES_BIG_ENDIAN"                                       
1235   "@                                                                       
1236    ins\\t%0.d[1], %1.d[0]                                                  
1237    ins\\t%0.d[1], %1"                                                      
1238   [(set_attr "type" "neon_ins")]                                           
1239 )     
the operands[0] is a inout reg, and the pattern also use (match_dup 0).

Another case in gcc/config/c6x/c6x.md
 440 (define_insn "*movstricthi_high"                                           
 441   [(set (match_operand:SI 0 "register_operand" "+ab")                      
 442         (ior:SI (and:SI (match_dup 0) (const_int 65535))                   
 443                 (ashift:SI (match_operand:SI 1 "const_int_operand" "IuB")  
 444                            (const_int 16))))]                              
 445   "reload_completed"                                                       
 446   "%|%.\\tmvklh\\t%$\\t%1, %0"                                             
 447   [(set_attr "units" "s")]) 

2930 (define_insn "setup_dsbt"                                                  
2931   [(set (match_operand:SI 0 "pic_register_operand" "+Z")                   
2932         (unspec:SI [(match_dup 0)                                          
2933                     (match_operand:SI 1 "symbolic_operand" "")]            
2934                    UNSPEC_SETUP_DSBT))]                                    
2935   "TARGET_DSBT"                                                            
2936   "%|%.\\tldw\\t%$\\t*+%0($DSBT_index%1), %0"                              
2937   [(set_attr "type" "load")                                                
2938    (set_attr "units" "d_addr")                                             
2939    (set_attr "dest_regfile" "b")                                           
2940    (set_attr "addr_regfile" "b")]) 


Do you mean that those pattern above are also wrong pattern ?
As you say that, that match_dup should not be used to tell the compiler that a
particular register is being used for two operands.
But I still think that the function can_assign_to_reg_without_clobbers_p can do
bettter, use max_reg_num to replace FIRST_PSEUDO_REGISTER * 2 and update
TEST_INSN when calling this function.

Reply via email to