在 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.


Reply via email to