在 2022/1/7 上午1:54, Xi Ruoyao 写道:
On Fri, 2021-12-24 at 17:28 +0800, chenglulu wrote:
+(define_insn "*zero_extendsidi2_internal"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+ (subreg:DI (match_operand:SI 1 "nonimmediate_operand" "r,ZC,W") 0))]
+ "TARGET_64BIT"
+ "@
+ bstrpick.d\t%0,%1,31,0
+ ldptr.w\t%0,%1\n\tlu32i.d\t%0,0
+ ld.wu\t%0,%1"
+ [(set_attr "move_type" "arith,load,load")
+ (set_attr "mode" "DI")
+ (set_attr "insn_count" "1,2,1")])
This pattern is generating wrong code, causing
FAIL: gcc.dg/compat/scalar-by-value-3 c_compat_x_tst.o-c_compat_y_tst.o execute
This failure is a real bug, the reduced testcase is attached. In the
assembly:
# ...
bstrins.d $r5,$r13,31,0
addi.d $r12,$r22,-228
bstrpick.d $r12,$r12,31,0
bstrins.d $r5,$r12,63,32
addi.w $r4,$r0,14 # 0xe
bl testvaci
This obviously does not make any sense: it calculates the *address* of
g[0]'s imaginary part, truncates it to 32-bit, then pass it as the
*value* of the imaginary part to testvaci().
The problem is: before the reload pass, the compiler consider g[0] a
(virtual) register. It only becomes MEM after the reload pass. Adding
reload_completed as the condition of this insn seems able to fix the
issue. However I'm not sure if other insns need the change too.
+;; See the comment before the *and<mode>3 pattern why this is generated by
+;; combine.
A minor issue: the comment before 'and<mode>3' does not exist.
Thanks, we are working on this. In addition, we will check other
instruction templates.