diff mbox series

[3/6] iq2000: Fix test and branch instructions

Message ID 20240620133418.350772-4-richard.sandiford@arm.com
State New
Headers show
Series Add a late-combine pass | expand

Commit Message

Richard Sandiford June 20, 2024, 1:34 p.m. UTC
The iq2000 test and branch instructions had patterns like:

  [(set (pc)
	(if_then_else
	 (eq (and:SI (match_operand:SI 0 "register_operand" "r")
		     (match_operand:SI 1 "power_of_2_operand" "I"))
	      (const_int 0))
	 (match_operand 2 "pc_or_label_operand" "")
	 (match_operand 3 "pc_or_label_operand" "")))]

power_of_2_operand allows any 32-bit power of 2, whereas "I" only
accepts 16-bit signed constants.  This meant that any power of 2
greater than 32768 would cause an "insn does not satisfy its
constraints" ICE.

Also, the %p operand modifier barfed on 1<<31, which is sign-
rather than zero-extended to 64 bits.  The code is inherently
limited to 32-bit operands -- power_of_2_operand contains a test
involving "unsigned" -- so this patch just ands with 0xffffffff.

gcc/
	* config/iq2000/iq2000.cc (iq2000_print_operand): Make %p handle 1<<31.
	* config/iq2000/iq2000.md: Remove "I" constraints on
	power_of_2_operands.
---
 gcc/config/iq2000/iq2000.cc | 2 +-
 gcc/config/iq2000/iq2000.md | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

Comments

Jeff Law June 21, 2024, 2:33 p.m. UTC | #1
On 6/20/24 7:34 AM, Richard Sandiford wrote:
> The iq2000 test and branch instructions had patterns like:
> 
>    [(set (pc)
> 	(if_then_else
> 	 (eq (and:SI (match_operand:SI 0 "register_operand" "r")
> 		     (match_operand:SI 1 "power_of_2_operand" "I"))
> 	      (const_int 0))
> 	 (match_operand 2 "pc_or_label_operand" "")
> 	 (match_operand 3 "pc_or_label_operand" "")))]
> 
> power_of_2_operand allows any 32-bit power of 2, whereas "I" only
> accepts 16-bit signed constants.  This meant that any power of 2
> greater than 32768 would cause an "insn does not satisfy its
> constraints" ICE.
> 
> Also, the %p operand modifier barfed on 1<<31, which is sign-
> rather than zero-extended to 64 bits.  The code is inherently
> limited to 32-bit operands -- power_of_2_operand contains a test
> involving "unsigned" -- so this patch just ands with 0xffffffff.
> 
> gcc/
> 	* config/iq2000/iq2000.cc (iq2000_print_operand): Make %p handle 1<<31.
> 	* config/iq2000/iq2000.md: Remove "I" constraints on
> 	power_of_2_operands.
OK for the trunk.
jeff
diff mbox series

Patch

diff --git a/gcc/config/iq2000/iq2000.cc b/gcc/config/iq2000/iq2000.cc
index f9f8c417841..136675d0fbb 100644
--- a/gcc/config/iq2000/iq2000.cc
+++ b/gcc/config/iq2000/iq2000.cc
@@ -3127,7 +3127,7 @@  iq2000_print_operand (FILE *file, rtx op, int letter)
     {
       int value;
       if (code != CONST_INT
-	  || (value = exact_log2 (INTVAL (op))) < 0)
+	  || (value = exact_log2 (UINTVAL (op) & 0xffffffff)) < 0)
 	output_operand_lossage ("invalid %%p value");
       else
 	fprintf (file, "%d", value);
diff --git a/gcc/config/iq2000/iq2000.md b/gcc/config/iq2000/iq2000.md
index 8617efac3c6..e62c250ce8c 100644
--- a/gcc/config/iq2000/iq2000.md
+++ b/gcc/config/iq2000/iq2000.md
@@ -1175,7 +1175,7 @@  (define_insn ""
   [(set (pc)
 	(if_then_else
 	 (eq (and:SI (match_operand:SI 0 "register_operand" "r")
-		     (match_operand:SI 1 "power_of_2_operand" "I"))
+		     (match_operand:SI 1 "power_of_2_operand"))
 	      (const_int 0))
 	 (match_operand 2 "pc_or_label_operand" "")
 	 (match_operand 3 "pc_or_label_operand" "")))]
@@ -1189,7 +1189,7 @@  (define_insn ""
   [(set (pc)
 	(if_then_else
 	 (ne (and:SI (match_operand:SI 0 "register_operand" "r")
-		     (match_operand:SI 1 "power_of_2_operand" "I"))
+		     (match_operand:SI 1 "power_of_2_operand"))
 	     (const_int 0))
 	 (match_operand 2 "pc_or_label_operand" "")
 	 (match_operand 3 "pc_or_label_operand" "")))]