diff mbox series

[NDS32] Fix nds32_split_ashiftdi3 with large shift amount

Message ID 1550824961-75218-1-git-send-email-kito@andestech.com
State New
Headers show
Series [NDS32] Fix nds32_split_ashiftdi3 with large shift amount | expand

Commit Message

Kito Cheng Feb. 22, 2019, 8:42 a.m. UTC
From: Kito Cheng <kito.cheng@gmail.com>

ChangeLog:
gcc/
	* config/nds32/nds32-md-auxiliary.c (nds32_split_ashiftdi3):
	Fix wrong code gen with large shift amount.
---
 gcc/config/nds32/nds32-md-auxiliary.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

Comments

Shiva Chen March 22, 2019, 9:30 a.m. UTC | #1
Hi Kito,
Thanks for the patch.

Kito Cheng <kito@andestech.com> 於 2019年2月22日 週五 下午4:42寫道:

> From: Kito Cheng <kito.cheng@gmail.com>
>
> ChangeLog:
> gcc/
>         * config/nds32/nds32-md-auxiliary.c (nds32_split_ashiftdi3):
>         Fix wrong code gen with large shift amount.
> ---
>  gcc/config/nds32/nds32-md-auxiliary.c | 21 ++++++++++++++-------
>  1 file changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/gcc/config/nds32/nds32-md-auxiliary.c
> b/gcc/config/nds32/nds32-md-auxiliary.c
> index 33844be..71fa421 100644
> --- a/gcc/config/nds32/nds32-md-auxiliary.c
> +++ b/gcc/config/nds32/nds32-md-auxiliary.c
> @@ -3304,15 +3304,22 @@ nds32_split_ashiftdi3 (rtx dst, rtx src, rtx
> shiftamount)
>        ext_start = gen_reg_rtx (SImode);
>
>        /*
> -        if (shiftamount < 32)
> +        # In fact, we want to check shift amonut is great than or equal
> 32,
> +        # but in some corner case, the shift amount might be very large
> value,
> +        # however we've defined SHIFT_COUNT_TRUNCATED, so GCC think we've
> +        # handle that correctly without any truncate.
>
The comments seem that defining SHIFT_COUNT_TRUNCATED will trigger the
issue.
But if we define SHIFT_COUNT_TRUNCATED as 0, the issue still occurs, right?

+        # so check the the condition of (shiftamount & 32) is most
> +        # safe way to do.
> +        if (shiftamount & 32)
> +          dst_low_part = 0
> +          dst_high_part = src_low_part << shiftamount & 0x1f
>
 shiftamount & 0x1f probably could remove because nds32 sll will read low
5-bits as the shift amount.

+        else
>            dst_low_part = src_low_part << shiftamout
>            dst_high_part = wext (src, 32 - shiftamount)
>            # wext can't handle wext (src, 32) since it's only take rb[0:4]
>            # for extract.
>            dst_high_part = shiftamount == 0 ? src_high_part : dst_high_part
> -        else
> -          dst_low_part = 0
> -          dst_high_part = src_low_part << shiftamount & 0x1f
> +
>        */
>
>        emit_insn (gen_subsi3 (ext_start,
> @@ -3331,11 +3338,11 @@ nds32_split_ashiftdi3 (rtx dst, rtx src, rtx
> shiftamount)
>        emit_insn (gen_ashlsi3 (dst_high_part_g32, src_low_part,
>                                                  new_shift_amout));
>
> -      emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32)));
> +      emit_insn (gen_andsi3 (select_reg, shiftamount, GEN_INT (32)));
>
> -      emit_insn (gen_cmovnsi (dst_low_part, select_reg,
> +      emit_insn (gen_cmovzsi (dst_low_part, select_reg,
>                               dst_low_part_l32, dst_low_part_g32));
> -      emit_insn (gen_cmovnsi (dst_high_part, select_reg,
> +      emit_insn (gen_cmovzsi (dst_high_part, select_reg,
>                               dst_high_part_l32, dst_high_part_g32));
>      }
>  }
>
Could you add a test case to illustrate the codgen changed by the patch?

Thanks,
Shiva
diff mbox series

Patch

diff --git a/gcc/config/nds32/nds32-md-auxiliary.c b/gcc/config/nds32/nds32-md-auxiliary.c
index 33844be..71fa421 100644
--- a/gcc/config/nds32/nds32-md-auxiliary.c
+++ b/gcc/config/nds32/nds32-md-auxiliary.c
@@ -3304,15 +3304,22 @@  nds32_split_ashiftdi3 (rtx dst, rtx src, rtx shiftamount)
       ext_start = gen_reg_rtx (SImode);
 
       /*
-	 if (shiftamount < 32)
+	 # In fact, we want to check shift amonut is great than or equal 32,
+	 # but in some corner case, the shift amount might be very large value,
+	 # however we've defined SHIFT_COUNT_TRUNCATED, so GCC think we've
+	 # handle that correctly without any truncate.
+	 # so check the the condition of (shiftamount & 32) is most
+	 # safe way to do.
+	 if (shiftamount & 32)
+	   dst_low_part = 0
+	   dst_high_part = src_low_part << shiftamount & 0x1f
+	 else
 	   dst_low_part = src_low_part << shiftamout
 	   dst_high_part = wext (src, 32 - shiftamount)
 	   # wext can't handle wext (src, 32) since it's only take rb[0:4]
 	   # for extract.
 	   dst_high_part = shiftamount == 0 ? src_high_part : dst_high_part
-	 else
-	   dst_low_part = 0
-	   dst_high_part = src_low_part << shiftamount & 0x1f
+
       */
 
       emit_insn (gen_subsi3 (ext_start,
@@ -3331,11 +3338,11 @@  nds32_split_ashiftdi3 (rtx dst, rtx src, rtx shiftamount)
       emit_insn (gen_ashlsi3 (dst_high_part_g32, src_low_part,
 						 new_shift_amout));
 
-      emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32)));
+      emit_insn (gen_andsi3 (select_reg, shiftamount, GEN_INT (32)));
 
-      emit_insn (gen_cmovnsi (dst_low_part, select_reg,
+      emit_insn (gen_cmovzsi (dst_low_part, select_reg,
 			      dst_low_part_l32, dst_low_part_g32));
-      emit_insn (gen_cmovnsi (dst_high_part, select_reg,
+      emit_insn (gen_cmovzsi (dst_high_part, select_reg,
 			      dst_high_part_l32, dst_high_part_g32));
     }
 }