public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-1622] RISC-V: Eliminate extension after for *w instructions
@ 2023-06-07 19:59 Jeff Law
0 siblings, 0 replies; only message in thread
From: Jeff Law @ 2023-06-07 19:59 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:99bfdb072e67fa3fe294d86b4b2a9f686f8d9705
commit r14-1622-g99bfdb072e67fa3fe294d86b4b2a9f686f8d9705
Author: Jeff Law <jlaw@ventanamicro.com>
Date: Wed Jun 7 13:40:16 2023 -0600
RISC-V: Eliminate extension after for *w instructions
This patch tries to prevent generating unnecessary sign extension
after *w instructions like "addiw" or "divw".
The main idea of it is to add SUBREG_PROMOTED fields during expanding.
I have tested on SPEC2017 there is no regression.
Only gcc.dg/pr30957-1.c test failed.
To solve that I did some changes in loop-iv.cc, but not sure that it is
suitable.
gcc/ChangeLog:
* config/riscv/bitmanip.md (rotrdi3, rotrsi3, rotlsi3): New expanders.
(rotrsi3_sext): Expose generator.
(rotlsi3 pattern): Hide generator.
* config/riscv/riscv-protos.h (riscv_emit_binary): New function
declaration.
* config/riscv/riscv.cc (riscv_emit_binary): Removed static
* config/riscv/riscv.md (addsi3, subsi3, negsi2): Hide generator.
(mulsi3, <optab>si3): Likewise.
(addsi3, subsi3, negsi2, mulsi3, <optab>si3): New expanders.
(addv<mode>4, subv<mode>4, mulv<mode>4): Use riscv_emit_binary.
(<u>mulsidi3): Likewise.
(addsi3_extended, subsi3_extended, negsi2_extended): Expose generator.
(mulsi3_extended, <optab>si3_extended): Likewise.
(splitter for shadd feeding divison): Update RTL pattern to account
for changes in how 32 bit ops are expanded for TARGET_64BIT.
* loop-iv.cc (get_biv_step_1): Process src of extension when it PLUS.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/shift-and-2.c: New tests.
* gcc.target/riscv/shift-shift-2.c: Adjust expected output.
* gcc.target/riscv/sign-extend.c: New test.
* gcc.target/riscv/zbb-rol-ror-03.c: Adjust expected output.
Co-authored-by: Jeff Law <jlaw@ventanamicro.com>
Diff:
---
gcc/config/riscv/bitmanip.md | 58 ++++++++--
gcc/config/riscv/riscv-protos.h | 1 +
gcc/config/riscv/riscv.cc | 2 +-
gcc/config/riscv/riscv.md | 147 ++++++++++++++++++++----
gcc/loop-iv.cc | 28 ++++-
gcc/testsuite/gcc.target/riscv/shift-and-2.c | 19 +++
gcc/testsuite/gcc.target/riscv/shift-shift-2.c | 5 +-
gcc/testsuite/gcc.target/riscv/sign-extend.c | 81 +++++++++++++
gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c | 3 +-
9 files changed, 309 insertions(+), 35 deletions(-)
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 96d31d92670..c42e7b890db 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -47,10 +47,10 @@
; implicit sign-extensions.
(define_split
[(set (match_operand:DI 0 "register_operand")
- (sign_extend:DI (div:SI (plus:SI (subreg:SI (ashift:DI (match_operand:DI 1 "register_operand")
- (match_operand:QI 2 "imm123_operand")) 0)
- (subreg:SI (match_operand:DI 3 "register_operand") 0))
- (subreg:SI (match_operand:DI 4 "register_operand") 0))))
+ (sign_extend:DI (div:SI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0)
+ (match_operand:QI 2 "imm123_operand"))
+ (subreg:SI (match_operand:DI 3 "register_operand") 0))
+ (subreg:SI (match_operand:DI 4 "register_operand") 0))))
(clobber (match_operand:DI 5 "register_operand"))]
"TARGET_64BIT && TARGET_ZBA"
[(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
@@ -304,11 +304,11 @@
[(set_attr "type" "bitmanip,load")
(set_attr "mode" "HI")])
-(define_expand "rotr<mode>3"
- [(set (match_operand:GPR 0 "register_operand")
- (rotatert:GPR (match_operand:GPR 1 "register_operand")
+(define_expand "rotrdi3"
+ [(set (match_operand:DI 0 "register_operand")
+ (rotatert:DI (match_operand:DI 1 "register_operand")
(match_operand:QI 2 "arith_operand")))]
- "TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB"
+ "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB)"
{
if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode))
FAIL;
@@ -322,6 +322,26 @@
"ror%i2%~\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
+(define_expand "rotrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (rotatert:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:QI 2 "arith_operand" "rI")))]
+ "TARGET_ZBB || TARGET_ZBKB || TARGET_XTHEADBB"
+{
+ if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode))
+ FAIL;
+ if (TARGET_64BIT && register_operand (operands[2], QImode))
+ {
+ rtx t = gen_reg_rtx (DImode);
+ emit_insn (gen_rotrsi3_sext (t, operands[1], operands[2]));
+ t = gen_lowpart (SImode, t);
+ SUBREG_PROMOTED_VAR_P (t) = 1;
+ SUBREG_PROMOTED_SET (t, SRP_SIGNED);
+ emit_move_insn (operands[0], t);
+ DONE;
+ }
+})
+
(define_insn "*rotrdi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(rotatert:DI (match_operand:DI 1 "register_operand" "r")
@@ -330,7 +350,7 @@
"ror%i2\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
-(define_insn "*rotrsi3_sext"
+(define_insn "rotrsi3_sext"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI (rotatert:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:QI 2 "arith_operand" "rI"))))]
@@ -338,7 +358,7 @@
"ror%i2%~\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
-(define_insn "rotlsi3"
+(define_insn "*rotlsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(rotate:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:QI 2 "register_operand" "r")))]
@@ -346,6 +366,24 @@
"rol%~\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
+(define_expand "rotlsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (rotate:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:QI 2 "register_operand" "r")))]
+ "TARGET_ZBB || TARGET_ZBKB"
+{
+ if (TARGET_64BIT)
+ {
+ rtx t = gen_reg_rtx (DImode);
+ emit_insn (gen_rotlsi3_sext (t, operands[1], operands[2]));
+ t = gen_lowpart (SImode, t);
+ SUBREG_PROMOTED_VAR_P (t) = 1;
+ SUBREG_PROMOTED_SET (t, SRP_SIGNED);
+ emit_move_insn (operands[0], t);
+ DONE;
+ }
+})
+
(define_insn "rotldi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(rotate:DI (match_operand:DI 1 "register_operand" "r")
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 9782f1794fb..38e4125424b 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -61,6 +61,7 @@ extern const char *riscv_output_return ();
extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx);
extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx);
extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx);
+extern rtx riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y);
#endif
extern bool riscv_expand_conditional_move (rtx, rtx, rtx, rtx);
extern rtx riscv_legitimize_call_address (rtx);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 60ebd9903e5..de30bf4e567 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1415,7 +1415,7 @@ riscv_emit_set (rtx target, rtx src)
/* Emit an instruction of the form (set DEST (CODE X Y)). */
-static rtx
+rtx
riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y)
{
return riscv_emit_set (dest, gen_rtx_fmt_ee (code, GET_MODE (dest), x, y));
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index be960583101..38b8fba2a53 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -513,7 +513,7 @@
[(set_attr "type" "fadd")
(set_attr "mode" "<UNITMODE>")])
-(define_insn "addsi3"
+(define_insn "*addsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (match_operand:SI 1 "register_operand" " r,r")
(match_operand:SI 2 "arith_operand" " r,I")))]
@@ -522,6 +522,24 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
+(define_expand "addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_operand:SI 1 "register_operand" " r,r")
+ (match_operand:SI 2 "arith_operand" " r,I")))]
+ ""
+{
+ if (TARGET_64BIT)
+ {
+ rtx t = gen_reg_rtx (DImode);
+ emit_insn (gen_addsi3_extended (t, operands[1], operands[2]));
+ t = gen_lowpart (SImode, t);
+ SUBREG_PROMOTED_VAR_P (t) = 1;
+ SUBREG_PROMOTED_SET (t, SRP_SIGNED);
+ emit_move_insn (operands[0], t);
+ DONE;
+ }
+})
+
(define_insn "adddi3"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(plus:DI (match_operand:DI 1 "register_operand" " r,r")
@@ -545,7 +563,7 @@
rtx t5 = gen_reg_rtx (DImode);
rtx t6 = gen_reg_rtx (DImode);
- emit_insn (gen_addsi3 (operands[0], operands[1], operands[2]));
+ riscv_emit_binary (PLUS, operands[0], operands[1], operands[2]);
if (GET_CODE (operands[1]) != CONST_INT)
emit_insn (gen_extend_insn (t4, operands[1], DImode, SImode, 0));
else
@@ -591,7 +609,7 @@
emit_insn (gen_extend_insn (t3, operands[1], DImode, SImode, 0));
else
t3 = operands[1];
- emit_insn (gen_addsi3 (operands[0], operands[1], operands[2]));
+ riscv_emit_binary (PLUS, operands[0], operands[1], operands[2]);
emit_insn (gen_extend_insn (t4, operands[0], DImode, SImode, 0));
riscv_expand_conditional_branch (operands[3], LTU, t4, t3);
@@ -606,7 +624,7 @@
DONE;
})
-(define_insn "*addsi3_extended"
+(define_insn "addsi3_extended"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(sign_extend:DI
(plus:SI (match_operand:SI 1 "register_operand" " r,r")
@@ -653,7 +671,7 @@
[(set_attr "type" "arith")
(set_attr "mode" "DI")])
-(define_insn "subsi3"
+(define_insn "*subsi3"
[(set (match_operand:SI 0 "register_operand" "= r")
(minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
(match_operand:SI 2 "register_operand" " r")))]
@@ -662,6 +680,24 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
+(define_expand "subsi3"
+ [(set (match_operand:SI 0 "register_operand" "= r")
+ (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
+ (match_operand:SI 2 "register_operand" " r")))]
+ ""
+{
+ if (TARGET_64BIT)
+ {
+ rtx t = gen_reg_rtx (DImode);
+ emit_insn (gen_subsi3_extended (t, operands[1], operands[2]));
+ t = gen_lowpart (SImode, t);
+ SUBREG_PROMOTED_VAR_P (t) = 1;
+ SUBREG_PROMOTED_SET (t, SRP_SIGNED);
+ emit_move_insn (operands[0], t);
+ DONE;
+ }
+})
+
(define_expand "subv<mode>4"
[(set (match_operand:GPR 0 "register_operand" "= r")
(minus:GPR (match_operand:GPR 1 "reg_or_0_operand" " rJ")
@@ -676,7 +712,7 @@
rtx t5 = gen_reg_rtx (DImode);
rtx t6 = gen_reg_rtx (DImode);
- emit_insn (gen_subsi3 (operands[0], operands[1], operands[2]));
+ riscv_emit_binary (MINUS, operands[0], operands[1], operands[2]);
if (GET_CODE (operands[1]) != CONST_INT)
emit_insn (gen_extend_insn (t4, operands[1], DImode, SImode, 0));
else
@@ -725,7 +761,7 @@
emit_insn (gen_extend_insn (t3, operands[1], DImode, SImode, 0));
else
t3 = operands[1];
- emit_insn (gen_subsi3 (operands[0], operands[1], operands[2]));
+ riscv_emit_binary (MINUS, operands[0], operands[1], operands[2]);
emit_insn (gen_extend_insn (t4, operands[0], DImode, SImode, 0));
riscv_expand_conditional_branch (operands[3], LTU, t3, t4);
@@ -741,7 +777,7 @@
})
-(define_insn "*subsi3_extended"
+(define_insn "subsi3_extended"
[(set (match_operand:DI 0 "register_operand" "= r")
(sign_extend:DI
(minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
@@ -770,7 +806,7 @@
[(set_attr "type" "arith")
(set_attr "mode" "DI")])
-(define_insn "negsi2"
+(define_insn "*negsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (match_operand:SI 1 "register_operand" " r")))]
""
@@ -778,7 +814,24 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
-(define_insn "*negsi2_extended"
+(define_expand "negsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_operand:SI 1 "register_operand" " r")))]
+ ""
+{
+ if (TARGET_64BIT)
+ {
+ rtx t = gen_reg_rtx (DImode);
+ emit_insn (gen_negsi2_extended (t, operands[1]));
+ t = gen_lowpart (SImode, t);
+ SUBREG_PROMOTED_VAR_P (t) = 1;
+ SUBREG_PROMOTED_SET (t, SRP_SIGNED);
+ emit_move_insn (operands[0], t);
+ DONE;
+ }
+})
+
+(define_insn "negsi2_extended"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI
(neg:SI (match_operand:SI 1 "register_operand" " r"))))]
@@ -814,7 +867,7 @@
[(set_attr "type" "fmul")
(set_attr "mode" "<UNITMODE>")])
-(define_insn "mulsi3"
+(define_insn "*mulsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (match_operand:SI 1 "register_operand" " r")
(match_operand:SI 2 "register_operand" " r")))]
@@ -823,6 +876,24 @@
[(set_attr "type" "imul")
(set_attr "mode" "SI")])
+(define_expand "mulsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (match_operand:SI 1 "register_operand" " r")
+ (match_operand:SI 2 "register_operand" " r")))]
+ "TARGET_ZMMUL || TARGET_MUL"
+{
+ if (TARGET_64BIT)
+ {
+ rtx t = gen_reg_rtx (DImode);
+ emit_insn (gen_mulsi3_extended (t, operands[1], operands[2]));
+ t = gen_lowpart (SImode, t);
+ SUBREG_PROMOTED_VAR_P (t) = 1;
+ SUBREG_PROMOTED_SET (t, SRP_SIGNED);
+ emit_move_insn (operands[0], t);
+ DONE;
+ }
+})
+
(define_insn "muldi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(mult:DI (match_operand:DI 1 "register_operand" " r")
@@ -868,8 +939,8 @@
emit_insn (gen_smul<mode>3_highpart (hp, operands[1], operands[2]));
emit_insn (gen_mul<mode>3 (operands[0], operands[1], operands[2]));
- emit_insn (gen_ashr<mode>3 (lp, operands[0],
- GEN_INT (BITS_PER_WORD - 1)));
+ riscv_emit_binary (ASHIFTRT, lp, operands[0],
+ GEN_INT (BITS_PER_WORD - 1));
riscv_expand_conditional_branch (operands[3], NE, hp, lp);
}
@@ -923,7 +994,7 @@
DONE;
})
-(define_insn "*mulsi3_extended"
+(define_insn "mulsi3_extended"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI
(mult:SI (match_operand:SI 1 "register_operand" " r")
@@ -1024,7 +1095,7 @@
"(TARGET_ZMMUL || TARGET_MUL) && !TARGET_64BIT"
{
rtx temp = gen_reg_rtx (SImode);
- emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
+ riscv_emit_binary (MULT, temp, operands[1], operands[2]);
emit_insn (gen_<su>mulsi3_highpart (riscv_subword (operands[0], true),
operands[1], operands[2]));
emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
@@ -1055,7 +1126,7 @@
"(TARGET_ZMMUL || TARGET_MUL) && !TARGET_64BIT"
{
rtx temp = gen_reg_rtx (SImode);
- emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
+ riscv_emit_binary (MULT, temp, operands[1], operands[2]);
emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
operands[1], operands[2]));
emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
@@ -1084,7 +1155,7 @@
;; ....................
;;
-(define_insn "<optab>si3"
+(define_insn "*<optab>si3"
[(set (match_operand:SI 0 "register_operand" "=r")
(any_div:SI (match_operand:SI 1 "register_operand" " r")
(match_operand:SI 2 "register_operand" " r")))]
@@ -1093,6 +1164,24 @@
[(set_attr "type" "idiv")
(set_attr "mode" "SI")])
+(define_expand "<optab>si3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (any_div:SI (match_operand:SI 1 "register_operand" " r")
+ (match_operand:SI 2 "register_operand" " r")))]
+ "TARGET_DIV"
+{
+ if (TARGET_64BIT)
+ {
+ rtx t = gen_reg_rtx (DImode);
+ emit_insn (gen_<optab>si3_extended (t, operands[1], operands[2]));
+ t = gen_lowpart (SImode, t);
+ SUBREG_PROMOTED_VAR_P (t) = 1;
+ SUBREG_PROMOTED_SET (t, SRP_SIGNED);
+ emit_move_insn (operands[0], t);
+ DONE;
+ }
+})
+
(define_insn "<optab>di3"
[(set (match_operand:DI 0 "register_operand" "=r")
(any_div:DI (match_operand:DI 1 "register_operand" " r")
@@ -1118,7 +1207,7 @@
DONE;
})
-(define_insn "*<optab>si3_extended"
+(define_insn "<optab>si3_extended"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI
(any_div:SI (match_operand:SI 1 "register_operand" " r")
@@ -2072,7 +2161,7 @@
;; expand_shift_1 can do this automatically when SHIFT_COUNT_TRUNCATED is
;; defined, but use of that is discouraged.
-(define_insn "<optab>si3"
+(define_insn "*<optab>si3"
[(set (match_operand:SI 0 "register_operand" "= r")
(any_shift:SI
(match_operand:SI 1 "register_operand" " r")
@@ -2088,6 +2177,24 @@
[(set_attr "type" "shift")
(set_attr "mode" "SI")])
+(define_expand "<optab>si3"
+ [(set (match_operand:SI 0 "register_operand" "= r")
+ (any_shift:SI (match_operand:SI 1 "register_operand" " r")
+ (match_operand:QI 2 "arith_operand" " rI")))]
+ ""
+{
+ if (TARGET_64BIT)
+ {
+ rtx t = gen_reg_rtx (DImode);
+ emit_insn (gen_<optab>si3_extend (t, operands[1], operands[2]));
+ t = gen_lowpart (SImode, t);
+ SUBREG_PROMOTED_VAR_P (t) = 1;
+ SUBREG_PROMOTED_SET (t, SRP_SIGNED);
+ emit_move_insn (operands[0], t);
+ DONE;
+ }
+})
+
(define_insn "<optab>di3"
[(set (match_operand:DI 0 "register_operand" "= r")
(any_shift:DI
@@ -2122,7 +2229,7 @@
[(set_attr "type" "shift")
(set_attr "mode" "<GPR:MODE>")])
-(define_insn "*<optab>si3_extend"
+(define_insn "<optab>si3_extend"
[(set (match_operand:DI 0 "register_operand" "= r")
(sign_extend:DI
(any_shift:SI (match_operand:SI 1 "register_operand" " r")
diff --git a/gcc/loop-iv.cc b/gcc/loop-iv.cc
index 6c40db947f7..858c5ee84f2 100644
--- a/gcc/loop-iv.cc
+++ b/gcc/loop-iv.cc
@@ -637,7 +637,7 @@ get_biv_step_1 (df_ref def, scalar_int_mode outer_mode, rtx reg,
{
rtx set, rhs, op0 = NULL_RTX, op1 = NULL_RTX;
rtx next, nextr;
- enum rtx_code code;
+ enum rtx_code code, prev_code = UNKNOWN;
rtx_insn *insn = DF_REF_INSN (def);
df_ref next_def;
enum iv_grd_result res;
@@ -697,6 +697,27 @@ get_biv_step_1 (df_ref def, scalar_int_mode outer_mode, rtx reg,
return false;
op0 = XEXP (rhs, 0);
+
+ /* rv64 wraps SImode arithmetic inside an extension to DImode.
+ This matches the actual hardware semantics. So peek inside
+ the extension and see if we have simple arithmetic that we
+ can analyze. */
+ if (GET_CODE (op0) == PLUS)
+ {
+ rhs = op0;
+ op0 = XEXP (rhs, 0);
+ op1 = XEXP (rhs, 1);
+
+ if (CONSTANT_P (op0))
+ std::swap (op0, op1);
+
+ if (!simple_reg_p (op0) || !CONSTANT_P (op1))
+ return false;
+
+ prev_code = code;
+ code = PLUS;
+ }
+
if (!simple_reg_p (op0))
return false;
@@ -769,6 +790,11 @@ get_biv_step_1 (df_ref def, scalar_int_mode outer_mode, rtx reg,
else
*outer_step = simplify_gen_binary (code, outer_mode,
*outer_step, op1);
+
+ if (prev_code == SIGN_EXTEND)
+ *extend = IV_SIGN_EXTEND;
+ else if (prev_code == ZERO_EXTEND)
+ *extend = IV_ZERO_EXTEND;
break;
case SIGN_EXTEND:
diff --git a/gcc/testsuite/gcc.target/riscv/shift-and-2.c b/gcc/testsuite/gcc.target/riscv/shift-and-2.c
index bc01e8ef992..ee9925b7498 100644
--- a/gcc/testsuite/gcc.target/riscv/shift-and-2.c
+++ b/gcc/testsuite/gcc.target/riscv/shift-and-2.c
@@ -38,5 +38,24 @@ sub6 (long i, long j)
{
return i << (j & 0x3f);
}
+
+/* Test for <optab>si3_extend. */
+int
+sub7 (int i, int j) {
+ return (i << 10) & j;
+}
+
+/* Test for <optab>si3_extend. */
+unsigned
+sub8 (unsigned i, unsigned j) {
+ return (i << 10) & j;
+}
+
+/* Test for <optab>si3_extend. */
+unsigned
+sub9 (unsigned i, unsigned j) {
+ return (i >> 10) & j;
+}
+
/* { dg-final { scan-assembler-not "andi" } } */
/* { dg-final { scan-assembler-not "sext.w" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/shift-shift-2.c b/gcc/testsuite/gcc.target/riscv/shift-shift-2.c
index 5f93be15ac5..bc8c4ef3828 100644
--- a/gcc/testsuite/gcc.target/riscv/shift-shift-2.c
+++ b/gcc/testsuite/gcc.target/riscv/shift-shift-2.c
@@ -38,5 +38,6 @@ sub5 (unsigned int i)
}
/* { dg-final { scan-assembler-times "slli" 5 } } */
/* { dg-final { scan-assembler-times "srli" 5 } } */
-/* { dg-final { scan-assembler-times "slliw" 1 } } */
-/* { dg-final { scan-assembler-times "srliw" 1 } } */
+/* { dg-final { scan-assembler-times ",40" 2 } } */ /* For sub5 test */
+/* { dg-final { scan-assembler-not "slliw" } } */
+/* { dg-final { scan-assembler-not "srliw" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sign-extend.c b/gcc/testsuite/gcc.target/riscv/sign-extend.c
new file mode 100644
index 00000000000..6f840194833
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sign-extend.c
@@ -0,0 +1,81 @@
+/* { dg-do compile { target { riscv64*-*-* } } } */
+/* { dg-options "-march=rv64gc -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+unsigned
+foo1 (unsigned x, unsigned y, unsigned z)
+{
+ return x & (y - z);
+}
+
+int
+foo2 (int x, int y, int z)
+{
+ return x & (y - z);
+}
+
+unsigned
+foo3 (unsigned x, unsigned y, unsigned z)
+{
+ return x & (y * z);
+}
+
+int
+foo4 (int x, int y, int z)
+{
+ return x & (y * z);
+}
+
+unsigned
+foo5 (unsigned x, unsigned y)
+{
+ return x & (y / x);
+}
+
+int
+foo6 (int x, int y)
+{
+ return x & (y / x);
+}
+
+unsigned
+foo7 (unsigned x, unsigned y)
+{
+ return x & (y % x);
+}
+
+int
+foo8 (int x, int y)
+{
+ return x & (y % x);
+}
+
+int
+foo9 (int x)
+{
+ return x & (-x);
+}
+
+unsigned
+foo10 (unsigned x, unsigned y)
+{
+ return x & (y + x);
+}
+
+
+unsigned
+foo11 (unsigned x)
+{
+ return x & (15 + x);
+}
+
+/* { dg-final { scan-assembler-times "subw" 2 } } */
+/* { dg-final { scan-assembler-times "addw" 1 } } */
+/* { dg-final { scan-assembler-times "addiw" 1 } } */
+/* { dg-final { scan-assembler-times "mulw" 2 } } */
+/* { dg-final { scan-assembler-times "divw" 1 } } */
+/* { dg-final { scan-assembler-times "divuw" 1 } } */
+/* { dg-final { scan-assembler-times "remw" 1 } } */
+/* { dg-final { scan-assembler-times "remuw" 1 } } */
+/* { dg-final { scan-assembler-times "negw" 1 } } */
+/* { dg-final { scan-assembler-not "sext.w" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c b/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c
index b44d7fe8920..e7e5cbb9a1a 100644
--- a/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c
+++ b/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c
@@ -16,4 +16,5 @@ unsigned int ror(unsigned int rs1, unsigned int rs2)
/* { dg-final { scan-assembler-times "rolw" 1 } } */
/* { dg-final { scan-assembler-times "rorw" 1 } } */
-/* { dg-final { scan-assembler-not "and" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "and" } } */
+/* { dg-final { scan-assembler-not "sext.w" } } */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-06-07 19:59 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-07 19:59 [gcc r14-1622] RISC-V: Eliminate extension after for *w instructions Jeff Law
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).