diff mbox

[PATCH/AARCH64v2,2/2] Fix PR 61345: rtx_cost ICEing on simple code

Message ID 1401757517-13460-2-git-send-email-apinski@cavium.com
State New
Headers show

Commit Message

Andrew Pinski June 3, 2014, 1:05 a.m. UTC
Hi,
  The problem here is aarch64_rtx_costs for IF_THEN_ELSE does not
handle the case where the first operand is a non comparison.  This
happens when the combine is combing a few RTLs and calling
set_src_cost to check the costs of the newly created rtl.

OK?  Built and tested on aarch64-elf with no regressions.

Thanks,
Andrew Pinski

ChangeLog:
	* config/aarch64/aarch64.c (aarch64_if_then_else_costs): Allow non comparisons
	for OP0.

testsuite/ChangeLog:
	* gcc.c-torture/compile/20140528-1.c: New testcase.

---
 gcc/config/aarch64/aarch64.c                     |   36 ++++++++++++++-------
 gcc/testsuite/gcc.c-torture/compile/20140528-1.c |    9 +++++
 2 files changed, 33 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/20140528-1.c

Comments

Marcus Shawcroft June 3, 2014, 8:38 a.m. UTC | #1
On 3 June 2014 02:05, Andrew Pinski <apinski@cavium.com> wrote:

> -         if (GET_CODE (op0) == NE
> -             || GET_CODE (op0) == EQ)
> +         if (cmpcode == NE
> +             || cmpcode == EQ)

Those two can go back on one line ?

>             }
> -         else if (GET_CODE (op0) == LT
> -                  || GET_CODE (op0) == GE)
> +         else if (cmpcode == LT
> +                  || cmpcode == GE)

Likewise?

OK

/Marcus
diff mbox

Patch

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 77a6706..ce4eb3c 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -4855,19 +4855,33 @@  aarch64_rtx_arith_op_extract_p (rtx x, enum machine_mode mode)
 static bool
 aarch64_if_then_else_costs (rtx op0, rtx op1, rtx op2, int *cost, bool speed)
 {
+  rtx inner;
+  rtx comparator;
+  enum rtx_code cmpcode;
+
+  if (COMPARISON_P (op0))
+    {
+      inner = XEXP (op0, 0);
+      comparator = XEXP (op0, 1);
+      cmpcode = GET_CODE (op0);
+    }
+  else
+    {
+      inner = op0;
+      comparator = const0_rtx;
+      cmpcode = NE;
+    }
+
   if (GET_CODE (op1) == PC || GET_CODE (op2) == PC)
     {
       /* Conditional branch.  */
-      if (GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
+      if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_CC)
 	return true;
       else
 	{
-	  if (GET_CODE (op0) == NE
-	      || GET_CODE (op0) == EQ)
+	  if (cmpcode == NE
+	      || cmpcode == EQ)
 	    {
-	      rtx inner = XEXP (op0, 0);
-	      rtx comparator = XEXP (op0, 1);
-
 	      if (comparator == const0_rtx)
 		{
 		  /* TBZ/TBNZ/CBZ/CBNZ.  */
@@ -4877,23 +4891,21 @@  aarch64_if_then_else_costs (rtx op0, rtx op1, rtx op2, int *cost, bool speed)
 			 	       0, speed);
 		else
 		  /* CBZ/CBNZ.  */
-		  *cost += rtx_cost (inner, GET_CODE (op0), 0, speed);
+		  *cost += rtx_cost (inner, cmpcode, 0, speed);
 
 	        return true;
 	      }
 	    }
-	  else if (GET_CODE (op0) == LT
-		   || GET_CODE (op0) == GE)
+	  else if (cmpcode == LT
+		   || cmpcode == GE)
 	    {
-	      rtx comparator = XEXP (op0, 1);
-
 	      /* TBZ/TBNZ.  */
 	      if (comparator == const0_rtx)
 		return true;
 	    }
 	}
     }
-  else if (GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
+  else if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_CC)
     {
       /* It's a conditional operation based on the status flags,
 	 so it must be some flavor of CSEL.  */
diff --git a/gcc/testsuite/gcc.c-torture/compile/20140528-1.c b/gcc/testsuite/gcc.c-torture/compile/20140528-1.c
new file mode 100644
index 0000000..d227802
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20140528-1.c
@@ -0,0 +1,9 @@ 
+unsigned f(unsigned flags, unsigned capabilities)
+{
+  unsigned gfp_mask;
+  unsigned gfp_notmask = 0;
+  gfp_mask = flags & ((1 << 25) - 1);
+  if (!(capabilities & 0x00000001))
+    gfp_mask |= 0x1000000u;
+  return (gfp_mask & ~gfp_notmask);
+}