[PATCH][GCC] arm: Fix MVE scalar shift intrinsics code-gen.
This patch modifies the MVE scalar shift RTL patterns. The current patterns have wrong constraints and predicates due to which the values returned from MVE scalar shift instructions are overwritten in the code-gen. example: $ cat x.c int32_t foo(int64_t acc, int shift) { return sqrshrl_sat48 (acc, shift); } Code-gen before applying this patch: $ arm-none-eabi-gcc -march=armv8.1-m.main+mve -mfloat-abi=hard -O2 -S $ cat x.s foo: push {r4, r5} sqrshrl r0, r1, #48, r2 ----> (a) mov r0, r4 ----> (b) pop {r4, r5} bx lr Code-gen after applying this patch: foo: sqrshrl r0, r1, #48, r2 bx lr In the current compiler the return value (r0) from sqrshrl (a) is getting overwritten by the mov statement (b). This patch fixes above issue. 2020-06-12 Srinath Parvathaneni <srinath.parvathaneni@arm.com> gcc/ * config/arm/mve.md (mve_uqrshll_sat<supf>_di): Correct the predicate and constraint of all the operands. (mve_sqrshrl_sat<supf>_di): Likewise. (mve_uqrshl_si): Likewise. (mve_sqrshr_si): Likewise. (mve_uqshll_di): Likewise. (mve_urshrl_di): Likewise. (mve_uqshl_si): Likewise. (mve_urshr_si): Likewise. (mve_sqshl_si): Likewise. (mve_srshr_si): Likewise. (mve_srshrl_di): Likewise. (mve_sqshll_di): Likewise. * config/arm/predicates.md (arm_low_register_operand): Define. gcc/testsuite/ * gcc.target/arm/mve/intrinsics/mve_scalar_shifts1.c: New test. * gcc.target/arm/mve/intrinsics/mve_scalar_shifts2.c: Likewise. * gcc.target/arm/mve/intrinsics/mve_scalar_shifts3.c: Likewise. * gcc.target/arm/mve/intrinsics/mve_scalar_shifts4.c: Likewise.
This commit is contained in:
parent
1160ec9a14
commit
6af598703f
@ -11344,9 +11344,9 @@
|
||||
;; [uqrshll_di]
|
||||
;;
|
||||
(define_insn "mve_uqrshll_sat<supf>_di"
|
||||
[(set (match_operand:DI 0 "arm_general_register_operand" "+r")
|
||||
(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "s_register_operand" "r")]
|
||||
[(set (match_operand:DI 0 "arm_low_register_operand" "=l")
|
||||
(unspec:DI [(match_operand:DI 1 "arm_low_register_operand" "0")
|
||||
(match_operand:SI 2 "register_operand" "r")]
|
||||
UQRSHLLQ))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"uqrshll%?\\t%Q1, %R1, #<supf>, %2"
|
||||
@ -11356,9 +11356,9 @@
|
||||
;; [sqrshrl_di]
|
||||
;;
|
||||
(define_insn "mve_sqrshrl_sat<supf>_di"
|
||||
[(set (match_operand:DI 0 "arm_general_register_operand" "+r")
|
||||
(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "s_register_operand" "r")]
|
||||
[(set (match_operand:DI 0 "arm_low_register_operand" "=l")
|
||||
(unspec:DI [(match_operand:DI 1 "arm_low_register_operand" "0")
|
||||
(match_operand:SI 2 "register_operand" "r")]
|
||||
SQRSHRLQ))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"sqrshrl%?\\t%Q1, %R1, #<supf>, %2"
|
||||
@ -11368,9 +11368,9 @@
|
||||
;; [uqrshl_si]
|
||||
;;
|
||||
(define_insn "mve_uqrshl_si"
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "+r")
|
||||
(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "s_register_operand" "r")]
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "=r")
|
||||
(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "0")
|
||||
(match_operand:SI 2 "register_operand" "r")]
|
||||
UQRSHL))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"uqrshl%?\\t%1, %2"
|
||||
@ -11380,9 +11380,9 @@
|
||||
;; [sqrshr_si]
|
||||
;;
|
||||
(define_insn "mve_sqrshr_si"
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "+r")
|
||||
(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "s_register_operand" "r")]
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "=r")
|
||||
(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "0")
|
||||
(match_operand:SI 2 "register_operand" "r")]
|
||||
SQRSHR))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"sqrshr%?\\t%1, %2"
|
||||
@ -11392,9 +11392,9 @@
|
||||
;; [uqshll_di]
|
||||
;;
|
||||
(define_insn "mve_uqshll_di"
|
||||
[(set (match_operand:DI 0 "arm_general_register_operand" "+r")
|
||||
(us_ashift:DI (match_operand:DI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
|
||||
[(set (match_operand:DI 0 "arm_low_register_operand" "=l")
|
||||
(us_ashift:DI (match_operand:DI 1 "arm_low_register_operand" "0")
|
||||
(match_operand:SI 2 "immediate_operand" "Pg")))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"uqshll%?\\t%Q1, %R1, %2"
|
||||
[(set_attr "predicable" "yes")])
|
||||
@ -11403,9 +11403,9 @@
|
||||
;; [urshrl_di]
|
||||
;;
|
||||
(define_insn "mve_urshrl_di"
|
||||
[(set (match_operand:DI 0 "arm_general_register_operand" "+r")
|
||||
(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
|
||||
[(set (match_operand:DI 0 "arm_low_register_operand" "=l")
|
||||
(unspec:DI [(match_operand:DI 1 "arm_low_register_operand" "0")
|
||||
(match_operand:SI 2 "immediate_operand" "Pg")]
|
||||
URSHRL))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"urshrl%?\\t%Q1, %R1, %2"
|
||||
@ -11415,9 +11415,9 @@
|
||||
;; [uqshl_si]
|
||||
;;
|
||||
(define_insn "mve_uqshl_si"
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "+r")
|
||||
(us_ashift:SI (match_operand:SI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "=r")
|
||||
(us_ashift:SI (match_operand:SI 1 "arm_general_register_operand" "0")
|
||||
(match_operand:SI 2 "immediate_operand" "Pg")))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"uqshl%?\\t%1, %2"
|
||||
[(set_attr "predicable" "yes")])
|
||||
@ -11426,9 +11426,9 @@
|
||||
;; [urshr_si]
|
||||
;;
|
||||
(define_insn "mve_urshr_si"
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "+r")
|
||||
(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "=r")
|
||||
(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "0")
|
||||
(match_operand:SI 2 "immediate_operand" "Pg")]
|
||||
URSHR))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"urshr%?\\t%1, %2"
|
||||
@ -11438,9 +11438,9 @@
|
||||
;; [sqshl_si]
|
||||
;;
|
||||
(define_insn "mve_sqshl_si"
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "+r")
|
||||
(ss_ashift:SI (match_operand:DI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "=r")
|
||||
(ss_ashift:SI (match_operand:DI 1 "arm_general_register_operand" "0")
|
||||
(match_operand:SI 2 "immediate_operand" "Pg")))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"sqshl%?\\t%1, %2"
|
||||
[(set_attr "predicable" "yes")])
|
||||
@ -11449,9 +11449,9 @@
|
||||
;; [srshr_si]
|
||||
;;
|
||||
(define_insn "mve_srshr_si"
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "+r")
|
||||
(unspec:SI [(match_operand:DI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
|
||||
[(set (match_operand:SI 0 "arm_general_register_operand" "=r")
|
||||
(unspec:SI [(match_operand:DI 1 "arm_general_register_operand" "0")
|
||||
(match_operand:SI 2 "immediate_operand" "Pg")]
|
||||
SRSHR))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"srshr%?\\t%1, %2"
|
||||
@ -11461,9 +11461,9 @@
|
||||
;; [srshrl_di]
|
||||
;;
|
||||
(define_insn "mve_srshrl_di"
|
||||
[(set (match_operand:DI 0 "arm_general_register_operand" "+r")
|
||||
(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
|
||||
[(set (match_operand:DI 0 "arm_low_register_operand" "=l")
|
||||
(unspec:DI [(match_operand:DI 1 "arm_low_register_operand" "0")
|
||||
(match_operand:SI 2 "immediate_operand" "Pg")]
|
||||
SRSHRL))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"srshrl%?\\t%Q1, %R1, %2"
|
||||
@ -11473,9 +11473,9 @@
|
||||
;; [sqshll_di]
|
||||
;;
|
||||
(define_insn "mve_sqshll_di"
|
||||
[(set (match_operand:DI 0 "arm_general_register_operand" "+r")
|
||||
(ss_ashift:DI (match_operand:DI 1 "arm_general_register_operand" "r")
|
||||
(match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
|
||||
[(set (match_operand:DI 0 "arm_low_register_operand" "=l")
|
||||
(ss_ashift:DI (match_operand:DI 1 "arm_low_register_operand" "0")
|
||||
(match_operand:SI 2 "immediate_operand" "Pg")))]
|
||||
"TARGET_HAVE_MVE"
|
||||
"sqshll%?\\t%Q1, %R1, %2"
|
||||
[(set_attr "predicable" "yes")])
|
||||
|
@ -155,6 +155,18 @@
|
||||
|| REGNO (op) >= FIRST_PSEUDO_REGISTER));
|
||||
})
|
||||
|
||||
;; Low core register, or any pseudo.
|
||||
(define_predicate "arm_low_register_operand"
|
||||
(match_code "reg,subreg")
|
||||
{
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
|
||||
return (REG_P (op)
|
||||
&& (REGNO (op) <= LAST_LO_REGNUM
|
||||
|| REGNO (op) >= FIRST_PSEUDO_REGISTER));
|
||||
})
|
||||
|
||||
(define_predicate "arm_general_adddi_operand"
|
||||
(ior (match_operand 0 "arm_general_register_operand")
|
||||
(and (match_code "const_int")
|
||||
|
@ -0,0 +1,40 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-add-options arm_v8_1m_mve } */
|
||||
|
||||
#include "arm_mve.h"
|
||||
#include "stdio.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
foo (int64_t acc, int shift)
|
||||
{
|
||||
acc = sqrshrl_sat48 (acc, shift);
|
||||
if (acc != 16)
|
||||
abort();
|
||||
acc = sqrshrl (acc, shift);
|
||||
if (acc != 2)
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
foo1 (uint64_t acc, int shift)
|
||||
{
|
||||
acc = uqrshll_sat48 (acc, shift);
|
||||
if (acc != 16)
|
||||
abort();
|
||||
acc = uqrshll (acc, shift);
|
||||
if (acc != 128)
|
||||
abort();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int64_t acc = 128;
|
||||
uint64_t acc1 = 2;
|
||||
int shift = 3;
|
||||
foo (acc, shift);
|
||||
foo1 (acc1, shift);
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-add-options arm_v8_1m_mve } */
|
||||
|
||||
#include "arm_mve.h"
|
||||
#include "stdio.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define IMM 3
|
||||
|
||||
void
|
||||
foo (int64_t acc, uint64_t acc1)
|
||||
{
|
||||
acc = sqshll (acc, IMM);
|
||||
if (acc != 128)
|
||||
abort();
|
||||
acc = srshrl (acc, IMM);
|
||||
if (acc != 16)
|
||||
abort();
|
||||
acc1 = uqshll (acc1, IMM);
|
||||
if (acc1 != 128)
|
||||
abort();
|
||||
acc1 = urshrl (acc1, IMM);
|
||||
if (acc1 != 16)
|
||||
abort();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int64_t acc = 16;
|
||||
uint64_t acc1 = 16;
|
||||
foo (acc, acc1);
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-add-options arm_v8_1m_mve } */
|
||||
|
||||
#include "arm_mve.h"
|
||||
#include "stdio.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
foo (int32_t acc, uint32_t acc1, int shift)
|
||||
{
|
||||
acc = sqrshr (acc, shift);
|
||||
if (acc != 16)
|
||||
abort();
|
||||
acc1 = uqrshl (acc1, shift);
|
||||
if (acc1 != 128)
|
||||
abort();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int32_t acc = 128;
|
||||
uint32_t acc1 = 16;
|
||||
int shift = 3;
|
||||
foo (acc, acc1, shift);
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-add-options arm_v8_1m_mve } */
|
||||
|
||||
#include "arm_mve.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define IMM 3
|
||||
|
||||
void
|
||||
foo (int32_t acc, uint32_t acc1)
|
||||
{
|
||||
acc = sqshl (acc, IMM);
|
||||
if (acc != 128)
|
||||
abort();
|
||||
acc = srshr (acc, IMM);
|
||||
if (acc != 16)
|
||||
abort();
|
||||
acc1 = uqshl (acc1, IMM);
|
||||
if (acc1 != 128)
|
||||
abort();
|
||||
acc1 = urshr (acc1, IMM);
|
||||
if (acc1 != 16)
|
||||
abort();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int32_t acc = 16;
|
||||
uint32_t acc1 = 16;
|
||||
foo (acc, acc1);
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user