Attaching the correct patch. 

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 9864e4344d2..c3739b2f331 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public 
License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
+#include <algorithm>
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
@@ -73,6 +74,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-address.h"
 #include "output.h"
 #include "builtins.h"
+#include "tree-vrp.h"
+
 
 /* Some systems use __main in a way incompatible with its use in gcc, in these
    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
@@ -3640,6 +3643,107 @@ expand_clobber (tree lhs)
     }
 }
 
+/* Print the ranges of the operand and save it to the dump file
+   used for debug purposes only.  */
+
+void
+print_range (tree operand, wide_int min, wide_int max)
+{
+  pretty_printer buffer;
+  pp_needs_newline (&buffer) = false;
+  buffer.buffer->stream = dump_file;
+  fprintf (dump_file, "Range for lhs: [");
+  pp_wide_int (&buffer, min, TYPE_SIGN (TREE_TYPE (operand)));
+  pp_printf (&buffer, ", ");
+  pp_wide_int (&buffer, max, TYPE_SIGN (TREE_TYPE (operand)));
+  pp_printf (&buffer, "]");
+  pp_flush (&buffer);
+  fprintf (dump_file, "\n");
+}
+
+
+
+/* Check that REG and SUBREG modes match between src and dest,
+   and that there is a cast to be removed.  */
+
+bool
+cast_to_remove_p (rtx src, rtx dest, machine_mode from
+                               , machine_mode to)
+{
+  if (GET_CODE (src) != SUBREG
+      || GET_CODE (dest) != SUBREG
+      || GET_CODE (SUBREG_REG (src)) != REG
+      || GET_CODE (SUBREG_REG (dest)) != REG
+      || GET_MODE (src) != GET_MODE (dest)
+      || GET_MODE (SUBREG_REG (src)) != GET_MODE (SUBREG_REG (dest))
+      || GET_MODE (src) != to
+      || GET_MODE (SUBREG_REG (src)) != from)
+    return false;
+  return true;
+}
+
+bool
+remove_cast_p (rtx temp, rtx target, gassign *assign_stmt)
+{
+  enum gimple_code code;
+  value_range_kind lhs_range, rhs_range;
+  unsigned int ops_num;
+  wide_int lhs_min, lhs_max, rhs_min, rhs_max;
+  if (gimple_assign_cast_p (assign_stmt))
+  {
+    code = gimple_code (assign_stmt);
+    ops_num = gimple_num_ops (assign_stmt);
+    if (code == GIMPLE_ASSIGN && ops_num < 3)
+    {
+      tree lhs = gimple_assign_lhs (assign_stmt);
+      if (POINTER_TYPE_P (TREE_TYPE (lhs)))
+       return false;
+      lhs_range = get_range_info (lhs, &lhs_min, &lhs_max);
+      if (dump_file && lhs_range == VR_RANGE)
+       print_range (lhs, lhs_min, lhs_max);
+
+      tree rhs = gimple_assign_rhs1 (assign_stmt);
+      if (POINTER_TYPE_P (TREE_TYPE (rhs)))
+       return false;
+      rhs_range = get_range_info (rhs, &rhs_min, &rhs_max);
+      if (rhs_range == VR_RANGE)
+      {
+       unsigned int rhs_precision
+        = std::max (wi::min_precision (rhs_max, TYPE_SIGN (TREE_TYPE (rhs))),
+               wi::min_precision (rhs_min, TYPE_SIGN (TREE_TYPE (rhs))));
+       unsigned int lhs_precision = TYPE_PRECISION (TREE_TYPE (lhs));
+       if (lhs_precision > rhs_precision)
+       {
+
+        if (dump_file)
+        {
+          print_range (rhs, rhs_min, rhs_max);
+          if (lhs_precision > rhs_precision)
+               fprintf (dump_file,
+                   "EXPAND-CAST: This casting can be optimized\n");
+        }
+
+        return cast_to_remove_p (temp,
+                        target,
+                        TYPE_MODE (TREE_TYPE (rhs)),
+                        TYPE_MODE (TREE_TYPE (lhs)));
+       }
+       else
+        if (dump_file)
+          fprintf (dump_file, "EXPAND-CAST: lhs_precision < rhs_precision\n");
+      }
+      else
+       if (dump_file)
+         fprintf (dump_file, "EXPAND-CAST: Range is not VR_RANGE\n");
+    }
+    else
+      if (dump_file)
+       fprintf (dump_file, "EXPAND-CAST: Got more than 2 ops \n");
+  }
+  return false;
+}
+
+
 /* A subroutine of expand_gimple_stmt, expanding one gimple statement
    STMT that doesn't require special handling for outgoing edges.  That
    is no tailcalls and no GIMPLE_COND.  */
@@ -3801,6 +3905,11 @@ expand_gimple_stmt_1 (gimple *stmt)
                    temp = convert_modes (GET_MODE (SUBREG_REG (target)),
                                          GET_MODE (target), temp, unsignedp);
                  }
+               if (targetm.remove_redundant_cast)
+                 if (remove_cast_p (temp,
+                                       target,
+                                       assign_stmt))
+                   temp = SUBREG_REG (temp);
 
                convert_move (SUBREG_REG (target), temp, unsignedp);
              }
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 94b5ac01762..504b1abf85e 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -5226,6 +5226,9 @@ riscv_hard_regno_rename_ok (unsigned from_regno 
ATTRIBUTE_UNUSED,
 #undef TARGET_MACHINE_DEPENDENT_REORG
 #define TARGET_MACHINE_DEPENDENT_REORG riscv_reorg
 
+#undef TARGET_REMOVE_REDUNDANT_CAST
+#define TARGET_REMOVE_REDUNDANT_CAST true
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-riscv.h"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 19985adac3e..3a0d4813d96 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -12194,3 +12194,9 @@ This target hook can be used to generate a 
target-specific code
 @deftypefn {Target Hook} void TARGET_RUN_TARGET_SELFTESTS (void)
 If selftests are enabled, run any selftests for this target.
 @end deftypefn
+
+@deftypevr {Target Hook} bool TARGET_REMOVE_REDUNDANT_CAST
+If this flag is true, @code{remove_cast_p} will be called
+and remove unneeded cast
+The default is false.
+@end deftypevr
\ No newline at end of file
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 1a16150bfc5..984e18e1697 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -8178,3 +8178,5 @@ maintainer is familiar with.
 @hook TARGET_SPECULATION_SAFE_VALUE
 
 @hook TARGET_RUN_TARGET_SELFTESTS
+
+@hook TARGET_REMOVE_REDUNDANT_CAST
\ No newline at end of file
diff --git a/gcc/target.def b/gcc/target.def
index b5e82ff826e..014e5a22d4d 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -6770,6 +6770,15 @@ following it should not be run.  Usually true only for 
virtual assembler\n\
 targets.",
 bool, false)
 
+/* True if remove_redundant_cast should be called to remove unneeded
+   casting.  */
+DEFHOOKPOD
+(remove_redundant_cast,
+ "If this flag is true, @code{remove_cast_p} will be called\n\
+and remove unneeded cast\n\
+The default is false.",
+ bool, false)
+
 /* Leave the boolean fields at the end.  */
 
 /* Functions related to mode switching.  */
@@ -6835,4 +6844,3 @@ DEFHOOK
 
 /* Close the 'struct gcc_target' definition.  */
 HOOK_VECTOR_END (C90_EMPTY_HACK)
-
diff --git a/gcc/testsuite/gcc.target/riscv/masking-to-byte-1.c 
b/gcc/testsuite/gcc.target/riscv/masking-to-byte-1.c
new file mode 100644
index 00000000000..4001deaef59
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/masking-to-byte-1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { riscv32*-*-* } } } */
+/* { dg-options "-Os" } */
+
+extern unsigned int func ();
+
+unsigned char
+foo (unsigned int arg)
+{
+  if (arg == 2)
+    return 0;
+
+  return (func() == arg || arg == 7);
+}
+
+/* { dg-final { scan-assembler-not "andi\\s+\\w\\d,\\w\\d,0xff" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/masking-to-byte-2.c 
b/gcc/testsuite/gcc.target/riscv/masking-to-byte-2.c
new file mode 100644
index 00000000000..96e2f3a6f71
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/masking-to-byte-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+/* This testcase is to show that the patch does not remove all the sign/zero 
extension.  */
+extern void bar(unsigned int x, unsigned int y, unsigned char index);
+
+void foo(void)
+{
+  unsigned int idx;
+
+  for(idx = 0; idx < 100; idx++)
+  {
+    bar(3, 0, (unsigned char)idx);
+  }
+}
+
+/* { dg-final { scan-assembler "andi\\s+\\w\\d,\\w\\d,0xff" } } */
\ No newline at end of file

-------------------------------------------
Change log:

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 085ef66a207..ffe7e061985 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2020-02-19  Nidal Faour <nidal.fa...@wdc.com>
+
+       * doc/tm.texi.in (TARGET_REMOVE_REDUNDANT_CAST): New hook.
+       * doc/tm.texi: Regenerate.
+       *cfgexpand.c (algorith.h): New include.
+       (tree-vrp.h): Likewise
+       (print_range): New function
+       (check_assign_can_be_free): Likewise
+       (adjust_assign_to_remove_cast): Likewise
+       (expand_gimple_stmt_1): Call adjust_assign_to_remove_cast
+       *config/riscv/riscv.c (TARGET_REMOVE_REDUNDANT_CAST): Define
+       *target.def (remove_redundant_cast): New target hook
+
 2020-03-09  Jason Merrill  <ja...@redhat.com>
 
        * gdbinit.in (pgs): Fix typo in documentation.

diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f91af78a302..c5a701e08af 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2020-02-19  Nidal Faour  <nidal.fa...@wdc.com>
+       * gcc.target/riscv/masking-to-byte-1.c: New test
+       * gcc.target/riscv/masking-to-byte-2.c: New test
+
 2020-03-09  Marek Polacek  <pola...@redhat.com>
 
        PR c++/92031 - bogus taking address of rvalue error.


Regards,
Nidal Faour

>-----Original Message-----
>From: David Malcolm <dmalc...@redhat.com>
>Sent: Wednesday, 11 March 2020 15:12
>To: Nidal Faour <nidal.fa...@wdc.com>; gcc-patches@gcc.gnu.org
>Cc: Ofer Shinaar <ofer.shin...@wdc.com>; Craig Blackmore
><craig.blackm...@embecosm.com>
>Subject: Re: Remove redundant zero extend
>
>CAUTION: This email originated from outside of Western Digital. Do not click
>on links or open attachments unless you recognize the sender and know that
>the content is safe.
>
>
>On Wed, 2020-03-11 at 13:04 +0000, Nidal Faour via Gcc-patches wrote:
>
>[...]
>
>> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index
>> f91af78a302..c5a701e08af 100644
>> --- a/gcc/testsuite/ChangeLog
>> +++ b/gcc/testsuite/ChangeLog
>> @@ -1,3 +1,7 @@
>> +2020-02-19  Nidal Faour  <nidal.fa...@wdc.com>
>> +       * gcc.target/riscv/masking-to-byte-1.c: New test
>> +       * gcc.target/riscv/masking-to-byte-2.c: New test
>> +
>> 2020-03-09  Marek Polacek  <pola...@redhat.com>
>>                 PR c++/92031 - bogus taking address of rvalue error.
>
>If I'm reading it right, the patch is missing these new testcases.
>
>Dave

Attachment: remove-redundant-zero-extend.patch
Description: remove-redundant-zero-extend.patch

Reply via email to