]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Eliminate extension after for *w instructions
authorJeff Law <jlaw@ventanamicro.com>
Wed, 7 Jun 2023 19:40:16 +0000 (13:40 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Wed, 7 Jun 2023 19:58:57 +0000 (13:58 -0600)
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>
gcc/config/riscv/bitmanip.md
gcc/config/riscv/riscv-protos.h
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.md
gcc/loop-iv.cc
gcc/testsuite/gcc.target/riscv/shift-and-2.c
gcc/testsuite/gcc.target/riscv/shift-shift-2.c
gcc/testsuite/gcc.target/riscv/sign-extend.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c

index 96d31d92670b27d495dc5a9fbfc07e8767f40976..c42e7b890db20cbda787860946147972a61d9b22 100644 (file)
 ; 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)))
   [(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;
   "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")
   "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"))))]
   "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")))]
   "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")
index 9782f1794fb9c45b048e6b5e30a9b2398d1e3af3..38e4125424bc6d4d563999b3328cb1ee0326b7c2 100644 (file)
@@ -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);
index 60ebd9903e53c3ebe0c4b6b22d88ef29950372f6..de30bf4e567b5e4906a72460cf636270f16b7dc3 100644 (file)
@@ -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));
index be9605831017ae79637ecad2a2002fca780f832c..38b8fba2a53942be3e4e1c666b889230f0cd827b 100644 (file)
   [(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")))]
   [(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")
       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
        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);
   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")
   [(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")))]
   [(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")
       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
        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);
 })
 
 
-(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")
   [(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")))]
   ""
   [(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"))))]
   [(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")))]
   [(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")
 
       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);
     }
   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")
   "(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));
   "(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));
 ;;  ....................
 ;;
 
-(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")))]
   [(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")
       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")
 ;; 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")
   [(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
   [(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")
index 6c40db947f7f549303f8bb4d4f38aa98b6561bcc..858c5ee84f25012f5390f15c52ba7a786507e552 100644 (file)
@@ -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:
index bc01e8ef99268ff154f0759620d501cadf338561..ee9925b749859950bd90de07aa63680bd3d8a5f2 100644 (file)
@@ -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" } } */
index 5f93be15ac5dc5234b75fb4004abd1fb4c37124d..bc8c4ef382897d849697e525986c4cdfa82f3699 100644 (file)
@@ -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 (file)
index 0000000..6f84019
--- /dev/null
@@ -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" } } */
index b44d7fe8920b3a6bdb81329626f20a508d0ca277..e7e5cbb9a1ab7b0af5b85c71fd4e2bd56aca3c00 100644 (file)
@@ -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" } } */