diff --git a/gcc/ChangeLog b/gcc/ChangeLog index becfda829d3..ece0da1eee6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,9 @@ -014-06-03 Andrew Pinski +2014-06-03 Andrew Pinski + + * config/aarch64/aarch64.c (aarch64_if_then_else_costs): Allow non comparisons + for OP0. + +2014-06-03 Andrew Pinski * config/aarch64/aarch64.c (aarch64_if_then_else_costs): New function. (aarch64_rtx_costs): Use aarch64_if_then_else_costs. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 0cddba4c919..3d5f48ce26a 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -4855,19 +4855,32 @@ 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 +4890,20 @@ 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/ChangeLog b/gcc/testsuite/ChangeLog index db89ee3974f..5098d409e89 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-06-03 Andrew Pinski + + * gcc.c-torture/compile/20140528-1.c: New testcase. + 2014-06-03 Dehao Chen * gcc.dg/tree-prof/merge_block.c: New test. 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 00000000000..d22780280b7 --- /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); +}