[4/5,ifcvt] optimize x=c ? (y op const_int) : y by RISC-V Zicond like insns

Message ID 20231205081248.2106-4-gaofei@eswincomputing.com
State Unresolved
Headers
Series [1/5,V3,ifcvt] optimize x=c ? (y op z) : y by RISC-V Zicond like insns |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Fei Gao Dec. 5, 2023, 8:12 a.m. UTC
  op=[PLUS, MINUS, IOR, XOR, ASHIFT, ASHIFTRT, LSHIFTRT, ROTATE, ROTATERT, AND]

Co-authored-by: Xiao Zeng<zengxiao@eswincomputing.com>

gcc/ChangeLog:

        * ifcvt.cc (noce_cond_zero_shift_op_supported): check if OP is shift like operation
        (noce_cond_zero_binary_op_supported): restructure & call noce_cond_zero_shift_op_supported
        (noce_bbs_ok_for_cond_zero_arith): add support for const_int
        (noce_try_cond_zero_arith): add support for x=c ? (y op const_int)

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/zicond_ifcvt_opt.c: add TCs for x=c ? (y op const_int) : y
---
 gcc/ifcvt.cc                                  |  45 +-
 .../gcc.target/riscv/zicond_ifcvt_opt.c       | 774 +++++++++++++++++-
 2 files changed, 811 insertions(+), 8 deletions(-)
  

Comments

Jeff Law Dec. 11, 2023, 5:38 a.m. UTC | #1
On 12/5/23 01:12, Fei Gao wrote:
> op=[PLUS, MINUS, IOR, XOR, ASHIFT, ASHIFTRT, LSHIFTRT, ROTATE, ROTATERT, AND]
> 
> Co-authored-by: Xiao Zeng<zengxiao@eswincomputing.com>
> 
> gcc/ChangeLog:
> 
>          * ifcvt.cc (noce_cond_zero_shift_op_supported): check if OP is shift like operation
>          (noce_cond_zero_binary_op_supported): restructure & call noce_cond_zero_shift_op_supported
>          (noce_bbs_ok_for_cond_zero_arith): add support for const_int
>          (noce_try_cond_zero_arith): add support for x=c ? (y op const_int)
> 
> gcc/testsuite/ChangeLog:
> 
>          * gcc.target/riscv/zicond_ifcvt_opt.c: add TCs for x=c ? (y op const_int) : y



> ---
>   gcc/ifcvt.cc                                  |  45 +-
>   .../gcc.target/riscv/zicond_ifcvt_opt.c       | 774 +++++++++++++++++-
>   2 files changed, 811 insertions(+), 8 deletions(-)
> 
> diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
> index 29f33f956eb..b84be53ec5c 100644
> --- a/gcc/ifcvt.cc
> +++ b/gcc/ifcvt.cc
> @@ -2910,6 +2910,20 @@ noce_try_sign_mask (struct noce_if_info *if_info)
>     return true;
>   }
>   
> +/*  Check if OP is shift-like operation supported by conditional zero
> +    based if conversion, returning TRUE if satisfied otherwise FALSE.
> +
> +    OP is the operation to check.  */
> +static bool
> +noce_cond_zero_shift_op_supported (enum rtx_code op)
> +{
> +  if (op == ASHIFT || op == ASHIFTRT || op == LSHIFTRT || op == ROTATE
> +      || op == ROTATERT)
> +    return true;
Formatting nit.  Go ahead and bring down the || op = ROTATE test as 
well.  That leaves the two lines better balanced with all the shifts on 
one line and all the rotates on another.  It's minor, but we might as 
well keep it easy to read.

> @@ -3089,7 +3111,18 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info)
>   	  return false;
>   	}
>   
> -      *to_replace = target;
> +      if (CONST_INT_P (*to_replace))
> +	{
> +	  if (noce_cond_zero_shift_op_supported (bin_code))
> +	    *to_replace = gen_rtx_SUBREG (E_QImode, target, 0);
> +	  else if (SUBREG_P (bin_op0))
> +	    *to_replace = gen_rtx_SUBREG (GET_MODE (bin_op0), target, 0);
> +	  else
> +	    *to_replace = target;
Not all targets use QImode for their shift counts, so you can't just 
force that argument to QImode.

The way this works in our internal tree is that we re-expand the binary 
operation rather than replacing bits of existing RTL.  That allows the 
expanders to do the right thing automatically for the target WRT 
handling of things like the mode of the shift count.  In fact, I don't 
see how you can ever do replacement of a constant with a register with 
the current scheme since the original constant will be modeless, so you 
never know what mode to use.



Jeff
  
Fei Gao Dec. 14, 2023, 8:42 a.m. UTC | #2
On 2023-12-11 13:38  Jeff Law <jeffreyalaw@gmail.com> wrote:
>
>
>
>On 12/5/23 01:12, Fei Gao wrote:
>> op=[PLUS, MINUS, IOR, XOR, ASHIFT, ASHIFTRT, LSHIFTRT, ROTATE, ROTATERT, AND]
>>
>> Co-authored-by: Xiao Zeng<zengxiao@eswincomputing.com>
>>
>> gcc/ChangeLog:
>>
>>          * ifcvt.cc (noce_cond_zero_shift_op_supported): check if OP is shift like operation
>>          (noce_cond_zero_binary_op_supported): restructure & call noce_cond_zero_shift_op_supported
>>          (noce_bbs_ok_for_cond_zero_arith): add support for const_int
>>          (noce_try_cond_zero_arith): add support for x=c ? (y op const_int)
>>
>> gcc/testsuite/ChangeLog:
>>
>>          * gcc.target/riscv/zicond_ifcvt_opt.c: add TCs for x=c ? (y op const_int) : y


>> @@ -3089,7 +3111,18 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info)
>>     return false;
>>   }
>>  
>> -      *to_replace = target;
>> +      if (CONST_INT_P (*to_replace))
>> +	{
>> +	  if (noce_cond_zero_shift_op_supported (bin_code))
>> +	    *to_replace = gen_rtx_SUBREG (E_QImode, target, 0);
>> +	  else if (SUBREG_P (bin_op0))
>> +	    *to_replace = gen_rtx_SUBREG (GET_MODE (bin_op0), target, 0);
>> +	  else
>> +	    *to_replace = target;
>Not all targets use QImode for their shift counts, so you can't just
>force that argument to QImode. 
Thanks for your info. I haven't understood the "complex" you mentioned
regarding subreg until now.

>
>The way this works in our internal tree is that we re-expand the binary
>operation rather than replacing bits of existing RTL.  That allows the
>expanders to do the right thing automatically for the target WRT
>handling of things like the mode of the shift count.  In fact, I don't
>see how you can ever do replacement of a constant with a register with
>the current scheme since the original constant will be modeless, so you
>never know what mode to use. 
Letting the expander to handle const_int case seems a target general solution.

BR, 
Fei

>
>
>
>Jeff
  

Patch

diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index 29f33f956eb..b84be53ec5c 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -2910,6 +2910,20 @@  noce_try_sign_mask (struct noce_if_info *if_info)
   return true;
 }
 
+/*  Check if OP is shift-like operation supported by conditional zero
+    based if conversion, returning TRUE if satisfied otherwise FALSE.
+
+    OP is the operation to check.  */
+static bool
+noce_cond_zero_shift_op_supported (enum rtx_code op)
+{
+  if (op == ASHIFT || op == ASHIFTRT || op == LSHIFTRT || op == ROTATE
+      || op == ROTATERT)
+    return true;
+
+  return false;
+}
+
 /*  Check if OP is supported by conditional zero based if conversion,
     returning TRUE if satisfied otherwise FALSE.
 
@@ -2921,8 +2935,7 @@  noce_cond_zero_binary_op_supported (rtx op)
   enum rtx_code opcode = GET_CODE (op);
 
   if (opcode == PLUS || opcode == MINUS || opcode == IOR || opcode == XOR
-      || opcode == ASHIFT || opcode == ASHIFTRT || opcode == LSHIFTRT
-      || opcode == ROTATE || opcode == ROTATERT || opcode == AND)
+      || opcode == AND || noce_cond_zero_shift_op_supported (opcode))
     return true;
 
   return false;
@@ -3009,7 +3022,7 @@  noce_bbs_ok_for_cond_zero_arith (struct noce_if_info *if_info, rtx *common_ptr,
   if (czero_code == UNKNOWN)
     return false;
 
-  if (REG_P (bin_op1))
+  if (CONST_INT_P (bin_op1) || REG_P (bin_op1))
     *to_replace = &XEXP (bin_exp, 1);
   else if (SUBREG_P (bin_op1))
     *to_replace = &SUBREG_REG (XEXP (bin_exp, 1));
@@ -3038,6 +3051,7 @@  noce_try_cond_zero_arith (struct noce_if_info *if_info)
   enum rtx_code czero_code = UNKNOWN;
   rtx bin_exp = NULL_RTX;
   enum rtx_code bin_code = UNKNOWN;
+  rtx bin_op0 = NULL_RTX;
   rtx non_zero_op = NULL_RTX;
   rtx *to_replace = NULL;
 
@@ -3048,6 +3062,7 @@  noce_try_cond_zero_arith (struct noce_if_info *if_info)
   start_sequence ();
 
   bin_code = GET_CODE (bin_exp);
+  bin_op0 = XEXP (bin_exp, 0);
 
   if (bin_code == AND)
     {
@@ -3074,9 +3089,16 @@  noce_try_cond_zero_arith (struct noce_if_info *if_info)
     }
   else
     {
-      non_zero_op = *to_replace;
+      if (CONST_INT_P (*to_replace))
+	{
+	  non_zero_op = gen_reg_rtx (mode);
+	  noce_emit_move_insn (non_zero_op, *to_replace);
+	}
+      else
+	non_zero_op = *to_replace;
+
       /* If x is used in both input and out like x = c ? x + z : x,
-	 use a new reg to avoid modifying x  */
+	     use a new reg to avoid modifying x  */
       if (common && rtx_equal_p (common, if_info->x))
 	target = gen_reg_rtx (mode);
       else
@@ -3089,7 +3111,18 @@  noce_try_cond_zero_arith (struct noce_if_info *if_info)
 	  return false;
 	}
 
-      *to_replace = target;
+      if (CONST_INT_P (*to_replace))
+	{
+	  if (noce_cond_zero_shift_op_supported (bin_code))
+	    *to_replace = gen_rtx_SUBREG (E_QImode, target, 0);
+	  else if (SUBREG_P (bin_op0))
+	    *to_replace = gen_rtx_SUBREG (GET_MODE (bin_op0), target, 0);
+	  else
+	    *to_replace = target;
+	}
+      else
+	*to_replace = target;
+
       noce_emit_move_insn (if_info->x, a);
     }
 
diff --git a/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c b/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c
index d5310690539..85743e1734c 100644
--- a/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c
+++ b/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c
@@ -615,6 +615,616 @@  test_RotateR_eqz (unsigned long x, unsigned long y, unsigned long z,
   return x;
 }
 
+long
+test_ADD_ceqz_imm (long x, long y, long c)
+{
+  if (c)
+    x = y + 11;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_ADD_ceqz_x_imm (long x, long c)
+{
+  if (c)
+    x = x + 11;
+
+  return x;
+}
+
+long
+test_ADD_nez_imm (long x, long y, long c)
+{
+  if (c)
+    x = y;
+  else
+    x = y + 11;
+  return x;
+}
+
+long
+test_ADD_nez_x_imm (long x, long c)
+{
+  if (c)
+    {
+    }
+  else
+    x = x + 11;
+  return x;
+}
+
+long
+test_ADD_nez_2_imm (long x, long y, long c)
+{
+  if (!c)
+    x = y + 11;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_ADD_nez_x_2_imm (long x, long c)
+{
+  if (!c)
+    x = x + 11;
+
+  return x;
+}
+
+long
+test_ADD_eqz_2_imm (long x, long y, long c)
+{
+  if (!c)
+    x = y;
+  else
+    x = y + 11;
+  return x;
+}
+
+long
+test_ADD_eqz_x_2_imm (long x, long c)
+{
+  if (!c)
+    {
+    }
+  else
+    x = x + 11;
+  return x;
+}
+
+long
+test_SUB_ceqz_imm (long x, long y, long c)
+{
+  if (c)
+    x = y - 11;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_SUB_ceqz_x_imm (long x, long c)
+{
+  if (c)
+    x = x - 11;
+
+  return x;
+}
+
+long
+test_SUB_nez_imm (long x, long y, long c)
+{
+  if (c)
+    x = y;
+  else
+    x = y - 11;
+  return x;
+}
+
+long
+test_SUB_nez_x_imm (long x, long c)
+{
+  if (c)
+    {
+    }
+  else
+    x = x - 11;
+  return x;
+}
+
+long
+test_SUB_nez_2_imm (long x, long y, long c)
+{
+  if (!c)
+    x = y - 11;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_SUB_nez_x_2_imm (long x, long c)
+{
+  if (!c)
+    x = x - 11;
+
+  return x;
+}
+
+long
+test_SUB_eqz_2_imm (long x, long y, long c)
+{
+  if (!c)
+    x = y;
+  else
+    x = y - 11;
+  return x;
+}
+
+long
+test_SUB_eqz_x_2_imm (long x, long c)
+{
+  if (!c)
+    {
+    }
+  else
+    x = x - 11;
+  return x;
+}
+
+long
+test_IOR_ceqz_imm (long x, long y, long c)
+{
+  if (c)
+    x = y | 11;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_IOR_ceqz_x_imm (long x, long c)
+{
+  if (c)
+    x = x | 11;
+
+  return x;
+}
+
+long
+test_IOR_nez_imm (long x, long y, long c)
+{
+  if (c)
+    x = y;
+  else
+    x = y | 11;
+  return x;
+}
+
+long
+test_IOR_nez_x_imm (long x, long c)
+{
+  if (c)
+    {
+    }
+  else
+    x = x | 11;
+  return x;
+}
+
+long
+test_IOR_nez_2_imm (long x, long y, long c)
+{
+  if (!c)
+    x = y | 11;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_IOR_nez_x_2_imm (long x, long c)
+{
+  if (!c)
+    x = x | 11;
+
+  return x;
+}
+
+long
+test_IOR_eqz_2_imm (long x, long y, long c)
+{
+  if (!c)
+    x = y;
+  else
+    x = y | 11;
+  return x;
+}
+
+long
+test_IOR_eqz_x_2_imm (long x, long c)
+{
+  if (!c)
+    {
+    }
+  else
+    x = x | 11;
+  return x;
+}
+
+long
+test_XOR_ceqz_imm (long x, long y, long c)
+{
+  if (c)
+    x = y ^ 11;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_XOR_ceqz_x_imm (long x, long c)
+{
+  if (c)
+    x = x ^ 11;
+
+  return x;
+}
+
+long
+test_XOR_nez_imm (long x, long y, long c)
+{
+  if (c)
+    x = y;
+  else
+    x = y ^ 11;
+  return x;
+}
+
+long
+test_XOR_nez_x_imm (long x, long c)
+{
+  if (c)
+    {
+    }
+  else
+    x = x ^ 11;
+  return x;
+}
+
+long
+test_XOR_nez_2_imm (long x, long y, long c)
+{
+  if (!c)
+    x = y ^ 11;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_XOR_nez_x_2_imm (long x, long c)
+{
+  if (!c)
+    x = x ^ 11;
+
+  return x;
+}
+
+long
+test_XOR_eqz_2_imm (long x, long y, long c)
+{
+  if (!c)
+    x = y;
+  else
+    x = y ^ 11;
+  return x;
+}
+
+long
+test_XOR_eqz_x_2_imm (long x, long c)
+{
+  if (!c)
+    {
+    }
+  else
+    x = x ^ 11;
+  return x;
+}
+
+long
+test_ADD_ceqz_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (c)
+    x = 11 + y;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_ADD_ceqz_x_imm_reverse_bin_oprands (long x, long c)
+{
+  if (c)
+    x = 11 + x;
+
+  return x;
+}
+
+long
+test_ADD_nez_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (c)
+    x = y;
+  else
+    x = 11 + y;
+  return x;
+}
+
+long
+test_ADD_nez_x_imm_reverse_bin_oprands (long x, long c)
+{
+  if (c)
+    {
+    }
+  else
+    x = 11 + x;
+  return x;
+}
+
+long
+test_ADD_nez_2_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (!c)
+    x = 11 + y;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_ADD_nez_x_2_imm_reverse_bin_oprands (long x, long c)
+{
+  if (!c)
+    x = 11 + x;
+
+  return x;
+}
+
+long
+test_ADD_eqz_2_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (!c)
+    x = y;
+  else
+    x = 11 + y;
+  return x;
+}
+
+long
+test_ADD_eqz_x_2_imm_reverse_bin_oprands (long x, long c)
+{
+  if (!c)
+    {
+    }
+  else
+    x = 11 + x;
+  return x;
+}
+
+long
+test_IOR_ceqz_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (c)
+    x = 11 | y;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_IOR_ceqz_x_imm_reverse_bin_oprands (long x, long c)
+{
+  if (c)
+    x = 11 | x;
+
+  return x;
+}
+
+long
+test_IOR_nez_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (c)
+    x = y;
+  else
+    x = 11 | y;
+  return x;
+}
+
+long
+test_IOR_nez_x_imm_reverse_bin_oprands (long x, long c)
+{
+  if (c)
+    {
+    }
+  else
+    x = 11 | x;
+  return x;
+}
+
+long
+test_IOR_nez_2_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (!c)
+    x = 11 | y;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_IOR_nez_x_2_imm_reverse_bin_oprands (long x, long c)
+{
+  if (!c)
+    x = 11 | x;
+
+  return x;
+}
+
+long
+test_IOR_eqz_2_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (!c)
+    x = y;
+  else
+    x = 11 | y;
+  return x;
+}
+
+long
+test_IOR_eqz_x_2_imm_reverse_bin_oprands (long x, long c)
+{
+  if (!c)
+    {
+    }
+  else
+    x = 11 | x;
+  return x;
+}
+
+long
+test_XOR_ceqz_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (c)
+    x = 11 ^ y;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_XOR_ceqz_x_imm_reverse_bin_oprands (long x, long c)
+{
+  if (c)
+    x = 11 ^ x;
+
+  return x;
+}
+
+long
+test_XOR_nez_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (c)
+    x = y;
+  else
+    x = 11 ^ y;
+  return x;
+}
+
+long
+test_XOR_nez_x_imm_reverse_bin_oprands (long x, long c)
+{
+  if (c)
+    {
+    }
+  else
+    x = 11 ^ x;
+  return x;
+}
+
+long
+test_XOR_nez_2_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (!c)
+    x = 11 ^ y;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_XOR_nez_x_2_imm_reverse_bin_oprands (long x, long c)
+{
+  if (!c)
+    x = 11 ^ x;
+
+  return x;
+}
+
+long
+test_XOR_eqz_2_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (!c)
+    x = y;
+  else
+    x = 11 ^ y;
+  return x;
+}
+
+long
+test_XOR_eqz_x_2_imm_reverse_bin_oprands (long x, long c)
+{
+  if (!c)
+    {
+    }
+  else
+    x = 11 ^ x;
+  return x;
+}
+
+long
+test_ShiftLeft_eqz_imm (long x, long y, long c)
+{
+  if (c)
+    x = y << 11;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_ShiftR_eqz_imm (long x, long y, long c)
+{
+  if (c)
+    x = y >> 11;
+  else
+    x = y;
+  return x;
+}
+
+unsigned long
+test_ShiftR_logical_eqz_imm (unsigned long x, unsigned long y, unsigned long z,
+			     unsigned long c)
+{
+  if (c)
+    x = y >> 11;
+  else
+    x = y;
+  return x;
+}
+
+unsigned long
+test_RotateL_eqz_imm (unsigned long x, unsigned long y, unsigned long c)
+{
+  if (c)
+    x = (y << 11) | (y >> (64 - 11));
+  else
+    x = y;
+  return x;
+}
+
+unsigned long
+test_RotateR_eqz_imm (unsigned long x, unsigned long y, unsigned long c)
+{
+  if (c)
+    x = (y >> 11) | (y << (64 - 11));
+  else
+    x = y;
+  return x;
+}
 long
 test_AND_ceqz (long x, long y, long z, long c)
 {
@@ -774,5 +1384,165 @@  test_AND_eqz_x_2_reverse_bin_oprands (long x, long z, long c)
     x = z & x;
   return x;
 }
-/* { dg-final { scan-assembler-times {czero\.eqz} 41 } } */
-/* { dg-final { scan-assembler-times {czero\.nez} 36 } } */
+
+long
+test_AND_ceqz_imm (long x, long y, long c)
+{
+  if (c)
+    x = y & 11;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_AND_ceqz_x_imm (long x, long c)
+{
+  if (c)
+    x = x & 11;
+
+  return x;
+}
+
+long
+test_AND_nez_imm (long x, long y, long c)
+{
+  if (c)
+    x = y;
+  else
+    x = y & 11;
+  return x;
+}
+
+long
+test_AND_nez_x_imm (long x, long c)
+{
+  if (c)
+    {
+    }
+  else
+    x = x & 11;
+  return x;
+}
+
+long
+test_AND_nez_2_imm (long x, long y, long c)
+{
+  if (!c)
+    x = y & 11;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_AND_nez_x_2_imm (long x, long c)
+{
+  if (!c)
+    x = x & 11;
+
+  return x;
+}
+
+long
+test_AND_eqz_2_imm (long x, long y, long c)
+{
+  if (!c)
+    x = y;
+  else
+    x = y & 11;
+  return x;
+}
+
+long
+test_AND_eqz_x_2_imm (long x, long c)
+{
+  if (!c)
+    {
+    }
+  else
+    x = x & 11;
+  return x;
+}
+
+long
+test_AND_ceqz_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (c)
+    x = 11 & y;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_AND_ceqz_x_imm_reverse_bin_oprands (long x, long c)
+{
+  if (c)
+    x = 11 & x;
+
+  return x;
+}
+
+long
+test_AND_nez_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (c)
+    x = y;
+  else
+    x = 11 & y;
+  return x;
+}
+
+long
+test_AND_nez_x_imm_reverse_bin_oprands (long x, long c)
+{
+  if (c)
+    {
+    }
+  else
+    x = 11 & x;
+  return x;
+}
+
+long
+test_AND_nez_2_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (!c)
+    x = 11 & y;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_AND_nez_x_2_imm_reverse_bin_oprands (long x, long c)
+{
+  if (!c)
+    x = 11 & x;
+
+  return x;
+}
+
+long
+test_AND_eqz_2_imm_reverse_bin_oprands (long x, long y, long c)
+{
+  if (!c)
+    x = y;
+  else
+    x = 11 & y;
+  return x;
+}
+
+long
+test_AND_eqz_x_2_imm_reverse_bin_oprands (long x, long c)
+{
+  if (!c)
+    {
+    }
+  else
+    x = 11 & x;
+  return x;
+}
+/* { dg-final { scan-assembler-times {czero\.eqz} 82 } } */
+/* { dg-final { scan-assembler-times {czero\.nez} 72 } } */