@@ -1222,48 +1222,50 @@
DONE;
})
-(define_insn_and_split "*mov<mode>_mem_to_mem"
+;; Some VLS modes (like V2SImode) have size <= a general purpose
+;; register width, we optimize such mem-to-mem move into mem-to-mem
+;; scalar move. Otherwise, we always force operands[1] into register
+;; so that we will never get mem-to-mem move after RA.
+(define_split
[(set (match_operand:VLS_AVL_IMM 0 "memory_operand")
(match_operand:VLS_AVL_IMM 1 "memory_operand"))]
- "TARGET_VECTOR && can_create_pseudo_p ()"
- "#"
- "&& 1"
+ "TARGET_VECTOR && can_create_pseudo_p ()
+ && GET_MODE_BITSIZE (<MODE>mode).to_constant () <= MAX_BITS_PER_WORD"
[(const_int 0)]
{
- if (GET_MODE_BITSIZE (<MODE>mode).to_constant () <= MAX_BITS_PER_WORD)
- {
- /* Opitmize the following case:
-
- typedef int8_t v2qi __attribute__ ((vector_size (2)));
- v2qi v = *(v2qi*)in;
- *(v2qi*)out = v;
-
- We prefer scalar load/store instead of vle.v/vse.v when
- the VLS modes size is smaller scalar mode. */
- machine_mode mode;
- unsigned size = GET_MODE_BITSIZE (<MODE>mode).to_constant ();
- if (FLOAT_MODE_P (<MODE>mode))
- mode = mode_for_size (size, MODE_FLOAT, 0).require ();
- else
- mode = mode_for_size (size, MODE_INT, 0).require ();
- emit_move_insn (gen_lowpart (mode, operands[0]),
- gen_lowpart (mode, operands[1]));
- }
+ /* Opitmize the following case:
+
+ typedef int8_t v2qi __attribute__ ((vector_size (2)));
+ v2qi v = *(v2qi*)in;
+ *(v2qi*)out = v;
+
+ We prefer scalar load/store instead of vle.v/vse.v when
+ the VLS modes size is smaller scalar mode. */
+ machine_mode mode;
+ unsigned size = GET_MODE_BITSIZE (<MODE>mode).to_constant ();
+ if (FLOAT_MODE_P (<MODE>mode))
+ mode = mode_for_size (size, MODE_FLOAT, 0).require ();
else
- {
- operands[1] = force_reg (<MODE>mode, operands[1]);
- emit_move_insn (operands[0], operands[1]);
- }
+ mode = mode_for_size (size, MODE_INT, 0).require ();
+ emit_move_insn (gen_lowpart (mode, operands[0]),
+ gen_lowpart (mode, operands[1]));
DONE;
}
- [(set_attr "type" "vmov")]
)
+;; We recognize mem-to-mem move in pre-RA stage so that we won't have
+;; ICE (unrecognizable insn: (set (mem) (mem))). Then, the previous
+;; mem-to-mem split pattern will force operands[1] into a register so
+;; that mem-to-mem move will never happen after RA.
+;;
+;; We don't allow mem-to-mem move in post-RA stage since we
+;; don't have an instruction to split mem-to-mem move after RA.
(define_insn_and_split "*mov<mode>"
[(set (match_operand:VLS_AVL_IMM 0 "reg_or_mem_operand" "=vr, m, vr")
(match_operand:VLS_AVL_IMM 1 "reg_or_mem_operand" " m,vr, vr"))]
"TARGET_VECTOR
- && (register_operand (operands[0], <MODE>mode)
+ && (can_create_pseudo_p ()
+ || register_operand (operands[0], <MODE>mode)
|| register_operand (operands[1], <MODE>mode))"
"@
#
new file mode 100644
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-march=rv64gcv -mabi=lp64d -Ofast -fallow-argument-mismatch -fmax-stack-var-size=65536 -S -std=legacy -w" }
+
+module a
+ integer,parameter :: SHR_KIND_R8 = selected_real_kind(12)
+end module a
+module b
+ use a, c => shr_kind_r8
+contains
+ subroutine d(cg , km, i1, i2)
+ real (c) ch(i2,km)
+ real (c) cg(4,i1:i2,km)
+ real dc(i2,km)
+ real(c) ci(i2,km)
+ real(c) cj(i2,km)
+ do k=2,ck
+ do i=i1,0
+ cl = ci(i,k) *ci(i,1) / cj(i,k)+ch(i,1)
+ cm = cg(1,i,k) - min(e,cg(1,i,co))
+ dc(i,k) = sign(cm, cl)
+ enddo
+ enddo
+ if ( cq == 0 ) then
+ do i=i1,i2
+ if( cr <= cs ) then
+ cg= sign( min(ct, cg), cg)
+ endif
+ enddo
+ endif
+ end subroutine d
+end module b