Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2015-01-18 Thread Christophe Lyon
On 16 January 2015 at 11:54, Marcus Shawcroft
marcus.shawcr...@gmail.com wrote:
 On 15 January 2015 at 18:18, Richard Henderson r...@redhat.com wrote:
 On 12/15/2014 12:41 AM, Zhenqiang Chen wrote:
 +(define_expand cmpmode
 +  [(set (match_operand 0 cc_register )
 +(match_operator:CC 1 aarch64_comparison_operator
 + [(match_operand:GPI 2 register_operand )
 +  (match_operand:GPI 3 aarch64_plus_operand )]))]
 +  
 +  
 +  operands[1] = gen_rtx_fmt_ee (COMPARE, SELECT_CC_MODE (GET_CODE 
 (operands[1]),
 +  operands[2],
 +  operands[3]),
 +  operands[2], operands[3]);
 +  
 +)

 Use { } not  for the C portion.

 Otherwise ok.

 Jiong... this is fine with me. /Marcus

Jiong,

I have noticed regressions on aarch64 after this patch:

See: 
http://abe.tcwglab.linaro.org/logs/validations/cross-validation/gcc/trunk/219723/report-build-info.html
Passed now fails  [PASS = FAIL]:
  gcc.target/aarch64/test_frame_1.c scan-assembler-times ldr\tx30,
\\[sp\\], [0-9]+ 3
  gcc.target/aarch64/test_frame_2.c scan-assembler-times ldp\tx19,
x30, \\[sp\\], [0-9]+ 2
  gcc.target/aarch64/test_frame_4.c scan-assembler-times ldp\tx19,
x30, \\[sp\\], [0-9]+ 2
  gcc.target/aarch64/test_frame_6.c scan-assembler-times ldr\tx30,
\\[sp\\], [0-9]+ 3
  gcc.target/aarch64/test_frame_7.c scan-assembler-times ldp\tx19,
x30, \\[sp\\], [0-9]+ 2

Is this expected?

Thanks,

Christophe.


Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2015-01-18 Thread Andrew Pinski
On Sun, Jan 18, 2015 at 11:58 AM, Christophe Lyon
christophe.l...@linaro.org wrote:
 On 16 January 2015 at 11:54, Marcus Shawcroft
 marcus.shawcr...@gmail.com wrote:
 On 15 January 2015 at 18:18, Richard Henderson r...@redhat.com wrote:
 On 12/15/2014 12:41 AM, Zhenqiang Chen wrote:
 +(define_expand cmpmode
 +  [(set (match_operand 0 cc_register )
 +(match_operator:CC 1 aarch64_comparison_operator
 + [(match_operand:GPI 2 register_operand )
 +  (match_operand:GPI 3 aarch64_plus_operand )]))]
 +  
 +  
 +  operands[1] = gen_rtx_fmt_ee (COMPARE, SELECT_CC_MODE (GET_CODE 
 (operands[1]),
 +  operands[2],
 +  operands[3]),
 +  operands[2], operands[3]);
 +  
 +)

 Use { } not  for the C portion.

 Otherwise ok.

 Jiong... this is fine with me. /Marcus

 Jiong,

 I have noticed regressions on aarch64 after this patch:

 See: 
 http://abe.tcwglab.linaro.org/logs/validations/cross-validation/gcc/trunk/219723/report-build-info.html
 Passed now fails  [PASS = FAIL]:
   gcc.target/aarch64/test_frame_1.c scan-assembler-times ldr\tx30,
 \\[sp\\], [0-9]+ 3
   gcc.target/aarch64/test_frame_2.c scan-assembler-times ldp\tx19,
 x30, \\[sp\\], [0-9]+ 2
   gcc.target/aarch64/test_frame_4.c scan-assembler-times ldp\tx19,
 x30, \\[sp\\], [0-9]+ 2
   gcc.target/aarch64/test_frame_6.c scan-assembler-times ldr\tx30,
 \\[sp\\], [0-9]+ 3
   gcc.target/aarch64/test_frame_7.c scan-assembler-times ldp\tx19,
 x30, \\[sp\\], [0-9]+ 2

 Is this expected?

Yes and now you just have to revert the revert of my patch to fix those.

Thanks,
Andrew


 Thanks,

 Christophe.


Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2015-01-18 Thread Christophe Lyon
On 18 January 2015 at 21:22, Andrew Pinski pins...@gmail.com wrote:
 On Sun, Jan 18, 2015 at 11:58 AM, Christophe Lyon
 christophe.l...@linaro.org wrote:
 On 16 January 2015 at 11:54, Marcus Shawcroft
 marcus.shawcr...@gmail.com wrote:
 On 15 January 2015 at 18:18, Richard Henderson r...@redhat.com wrote:
 On 12/15/2014 12:41 AM, Zhenqiang Chen wrote:
 +(define_expand cmpmode
 +  [(set (match_operand 0 cc_register )
 +(match_operator:CC 1 aarch64_comparison_operator
 + [(match_operand:GPI 2 register_operand )
 +  (match_operand:GPI 3 aarch64_plus_operand )]))]
 +  
 +  
 +  operands[1] = gen_rtx_fmt_ee (COMPARE, SELECT_CC_MODE (GET_CODE 
 (operands[1]),
 +  operands[2],
 +  operands[3]),
 +  operands[2], operands[3]);
 +  
 +)

 Use { } not  for the C portion.

 Otherwise ok.

 Jiong... this is fine with me. /Marcus

 Jiong,

 I have noticed regressions on aarch64 after this patch:

 See: 
 http://abe.tcwglab.linaro.org/logs/validations/cross-validation/gcc/trunk/219723/report-build-info.html
 Passed now fails  [PASS = FAIL]:
   gcc.target/aarch64/test_frame_1.c scan-assembler-times ldr\tx30,
 \\[sp\\], [0-9]+ 3
   gcc.target/aarch64/test_frame_2.c scan-assembler-times ldp\tx19,
 x30, \\[sp\\], [0-9]+ 2
   gcc.target/aarch64/test_frame_4.c scan-assembler-times ldp\tx19,
 x30, \\[sp\\], [0-9]+ 2
   gcc.target/aarch64/test_frame_6.c scan-assembler-times ldr\tx30,
 \\[sp\\], [0-9]+ 3
   gcc.target/aarch64/test_frame_7.c scan-assembler-times ldp\tx19,
 x30, \\[sp\\], [0-9]+ 2

 Is this expected?

 Yes and now you just have to revert the revert of my patch to fix those.

Thanks for the clarification/confirmation, I thought I had seen
something like that but I was confused.

 Thanks,
 Andrew


 Thanks,

 Christophe.


Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2015-01-16 Thread Marcus Shawcroft
On 15 January 2015 at 18:18, Richard Henderson r...@redhat.com wrote:
 On 12/15/2014 12:41 AM, Zhenqiang Chen wrote:
 +(define_expand cmpmode
 +  [(set (match_operand 0 cc_register )
 +(match_operator:CC 1 aarch64_comparison_operator
 + [(match_operand:GPI 2 register_operand )
 +  (match_operand:GPI 3 aarch64_plus_operand )]))]
 +  
 +  
 +  operands[1] = gen_rtx_fmt_ee (COMPARE, SELECT_CC_MODE (GET_CODE 
 (operands[1]),
 +  operands[2],
 +  operands[3]),
 +  operands[2], operands[3]);
 +  
 +)

 Use { } not  for the C portion.

 Otherwise ok.

Jiong... this is fine with me. /Marcus


Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2015-01-15 Thread Richard Henderson
On 12/15/2014 12:41 AM, Zhenqiang Chen wrote:
 +(define_expand cmpmode
 +  [(set (match_operand 0 cc_register )
 +(match_operator:CC 1 aarch64_comparison_operator
 + [(match_operand:GPI 2 register_operand )
 +  (match_operand:GPI 3 aarch64_plus_operand )]))]
 +  
 +  
 +  operands[1] = gen_rtx_fmt_ee (COMPARE, SELECT_CC_MODE (GET_CODE 
 (operands[1]),
 +  operands[2],
 +  operands[3]),
 +  operands[2], operands[3]);
 +  
 +)

Use { } not  for the C portion.

Otherwise ok.


r~


Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2015-01-15 Thread Jiong Wang

On 15/12/14 08:41, Zhenqiang Chen wrote:




-Original Message-
From: Richard Henderson [mailto:r...@redhat.com]
Sent: Saturday, December 13, 2014 3:26 AM
To: Zhenqiang Chen
Cc: Marcus Shawcroft; gcc-patches@gcc.gnu.org
Subject: Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)


- tree lhs = gimple_assign_lhs (g);
  enum machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
  rtx target = gen_reg_rtx (mode);
+
+ start_sequence ();
  tmp = emit_cstore (target, icode, NE, cc_mode, cc_mode,
 0, tmp, const0_rtx, 1, mode);
  if (tmp)
-   return tmp;
+   {
+ rtx seq = get_insns ();
+ end_sequence ();
+ emit_insn (prep_seq);
+ emit_insn (gen_seq);
+ emit_insn (seq);
+ return tmp;
+   }
+ end_sequence ();

Given that you're already doing delete_insns_since (last) at the end of this
function, I don't think you need a new sequence around the emit_cstore.
Just

emit_insn (prep_seq);
emit_insn (gen_seq);
tmp = emit_cstore (...);
if (tmp)
  return tmp;

Updated.
  

+  int unsignedp = code == LTU || code == LEU || code == GTU || code
+ == GEU;

You don't need to examine the code, you can look at the argument:

   TYPE_UNSIGNED (TREE_TYPE (treeop0))
  
Updated.
  

+  op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode,
+ unsignedp);
+  op1 = prepare_operand (icode, op1, 3, op_mode, cmp_mode,
+ unsignedp);  if (!op0 || !op1)
+{
+  end_sequence ();
+  return NULL_RTX;
+}
+  *prep_seq = get_insns ();
+  end_sequence ();
+
+  cmp = gen_rtx_fmt_ee ((enum rtx_code) code, cmp_mode, op0, op1);
+ target = gen_rtx_REG (CCmode, CC_REGNUM);
+
+  create_output_operand (ops[0], target, CCmode);
+ create_fixed_operand (ops[1], cmp);  create_fixed_operand (ops[2],
+ op0);  create_fixed_operand (ops[3], op1);

Hmm.  With so many fixed operands, I think you may be better off not
creating the cmpmode expander in the first place.  Just inline the
SELECT_CC_MODE and everything right here.

In the patch, I use prepare_operand (icode, op0, 2, ...) to do the operand MODE 
conversion (from HI/QI to SI), which needs a cmpmode expander. Without it, I 
have to add additional codes to do the conversion (as it in previous patch, which 
leads to PR64015).


Ping~,

verified this patch will pass speck2k6 build without ICE anymore.



Thanks!
-Zhenqiang





RE: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2014-12-15 Thread Zhenqiang Chen


 -Original Message-
 From: Richard Henderson [mailto:r...@redhat.com]
 Sent: Saturday, December 13, 2014 3:26 AM
 To: Zhenqiang Chen
 Cc: Marcus Shawcroft; gcc-patches@gcc.gnu.org
 Subject: Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)
 
  - tree lhs = gimple_assign_lhs (g);
enum machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
rtx target = gen_reg_rtx (mode);
  +
  + start_sequence ();
tmp = emit_cstore (target, icode, NE, cc_mode, cc_mode,
   0, tmp, const0_rtx, 1, mode);
if (tmp)
  -   return tmp;
  +   {
  + rtx seq = get_insns ();
  + end_sequence ();
  + emit_insn (prep_seq);
  + emit_insn (gen_seq);
  + emit_insn (seq);
  + return tmp;
  +   }
  + end_sequence ();
 
 Given that you're already doing delete_insns_since (last) at the end of this
 function, I don't think you need a new sequence around the emit_cstore.
 Just
 
   emit_insn (prep_seq);
   emit_insn (gen_seq);
   tmp = emit_cstore (...);
   if (tmp)
 return tmp;

Updated.
 
  +  int unsignedp = code == LTU || code == LEU || code == GTU || code
  + == GEU;
 
 You don't need to examine the code, you can look at the argument:
 
   TYPE_UNSIGNED (TREE_TYPE (treeop0))
 
Updated. 
 
  +  op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode,
  + unsignedp);
  +  op1 = prepare_operand (icode, op1, 3, op_mode, cmp_mode,
  + unsignedp);  if (!op0 || !op1)
  +{
  +  end_sequence ();
  +  return NULL_RTX;
  +}
  +  *prep_seq = get_insns ();
  +  end_sequence ();
  +
  +  cmp = gen_rtx_fmt_ee ((enum rtx_code) code, cmp_mode, op0, op1);
  + target = gen_rtx_REG (CCmode, CC_REGNUM);
  +
  +  create_output_operand (ops[0], target, CCmode);
  + create_fixed_operand (ops[1], cmp);  create_fixed_operand (ops[2],
  + op0);  create_fixed_operand (ops[3], op1);
 
 Hmm.  With so many fixed operands, I think you may be better off not
 creating the cmpmode expander in the first place.  Just inline the
 SELECT_CC_MODE and everything right here.

In the patch, I use prepare_operand (icode, op0, 2, ...) to do the operand MODE 
conversion (from HI/QI to SI), which needs a cmpmode expander. Without it, I 
have to add additional codes to do the conversion (as it in previous patch, 
which leads to PR64015).

Thanks!
-Zhenqiang

gen-ccmp-v2.patch
Description: Binary data


Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2014-12-12 Thread Richard Henderson
 -   tree lhs = gimple_assign_lhs (g);
 enum machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
 rtx target = gen_reg_rtx (mode);
 +
 +   start_sequence ();
 tmp = emit_cstore (target, icode, NE, cc_mode, cc_mode,
0, tmp, const0_rtx, 1, mode);
 if (tmp)
 - return tmp;
 + {
 +   rtx seq = get_insns ();
 +   end_sequence ();
 +   emit_insn (prep_seq);
 +   emit_insn (gen_seq);
 +   emit_insn (seq);
 +   return tmp;
 + }
 +   end_sequence ();

Given that you're already doing delete_insns_since (last)
at the end of this function, I don't think you need a new
sequence around the emit_cstore.  Just

emit_insn (prep_seq);
emit_insn (gen_seq);
tmp = emit_cstore (...);
if (tmp)
  return tmp;

 +  int unsignedp = code == LTU || code == LEU || code == GTU || code == GEU;

You don't need to examine the code, you can look at the argument:

  TYPE_UNSIGNED (TREE_TYPE (treeop0))



 +  op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode, unsignedp);
 +  op1 = prepare_operand (icode, op1, 3, op_mode, cmp_mode, unsignedp);
 +  if (!op0 || !op1)
 +{
 +  end_sequence ();
 +  return NULL_RTX;
 +}
 +  *prep_seq = get_insns ();
 +  end_sequence ();
 +
 +  cmp = gen_rtx_fmt_ee ((enum rtx_code) code, cmp_mode, op0, op1);
 +  target = gen_rtx_REG (CCmode, CC_REGNUM);
 +
 +  create_output_operand (ops[0], target, CCmode);
 +  create_fixed_operand (ops[1], cmp);
 +  create_fixed_operand (ops[2], op0);
 +  create_fixed_operand (ops[3], op1);

Hmm.  With so many fixed operands, I think you may be better off not
creating the cmpmode expander in the first place.  Just inline the
SELECT_CC_MODE and everything right here.


r~


RE: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2014-12-11 Thread Zhenqiang Chen


 -Original Message-
 From: Richard Henderson [mailto:r...@redhat.com]
 Sent: Tuesday, November 25, 2014 5:25 PM
 To: Zhenqiang Chen
 Cc: Marcus Shawcroft; gcc-patches@gcc.gnu.org
 Subject: Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)
 
 On 11/25/2014 09:41 AM, Zhenqiang Chen wrote:
  I want to confirm with you two things before I rework it.
  (1) expand_insn needs an optab_handler as input. Do I need to define a
 ccmp_optab with different mode support in optabs.def?
 
 No, look again: expand_insn needs an enum insn_code as input.  Since this is
 the backend, you can use any icode name you like, which means that you can
 use CODE_FOR_ccmp_and etc directly.
 
  (2) To make sure later operands not clobber CC, all operands are expanded
 before ccmp-first in current implementation. If taking tree/gimple as input,
 what's your preferred logic to guarantee CC not clobbered?
 
 Hmm.  Perhaps the target hook will need to output two sequences, each of
 which will be concatenated while looping around the calls to gen_ccmp_next.
 The first sequence will be operand preparation and the second sequence will
 be ccmp generation.
 
 Something like
 
 bool
 aarch64_gen_ccmp_start(rtx *prep_seq, rtx *gen_seq,
int cmp_code, int bit_code,
tree op0, tree op1) {
   bool success;
 
   start_sequence ();
   // Widen and expand operands
   *prep_seq = get_insns ();
   end_sequence ();
 
   start_sequence ();
   // Generate the first compare
   *gen_seq = get_insns ();
   end_sequence ();
 
   return success;
 }
 
 bool
 aarch64_gen_ccmp_next(rtx *prep_seq, rtx *gen_seq,
   rtx prev, int cmp_code, int bit_code,
   tree op0, tree op1) {
   bool success;
 
   push_to_sequence (*prep_seq);
   // Widen and expand operands
   *prep_seq = get_insns ();
   end_sequence ();
 
   push_to_sequence (*gen_seq);
   // Generate the next ccmp
   *gen_seq = get_insns ();
   end_sequence ();
 
   return success;
 }
 
 If there are ever any failures, the middle-end can simply discard the
 sequences.  If everything succeeds, it simply calls emit_insn on both
 sequences.
 
 
Thanks for the comments. The updated patch is attached.

Note: Function aarch64_code_to_ccmode is the same as it before reverting.

ChangeLog:
2014-12-12  Zhenqiang Chen  zhenqiang.c...@arm.com

* ccmp.c (expand_ccmp_next): New function.
(expand_ccmp_expr_1, expand_ccmp_expr): Handle operand insn sequence
and compare insn sequence.
* config/aarch64/aarch64.c (aarch64_code_to_ccmode,
aarch64_gen_ccmp_first, aarch64_gen_ccmp_next): New functions.
(TARGET_GEN_CCMP_FIRST, TARGET_GEN_CCMP_NEXT): New MICRO.
* config/aarch64/aarch64.md (*ccmp_and): Changed to ccmp_andmode.
(*ccmp_ior): Changed to ccmp_iormode.
(cmpmode): New pattern.
* doc/tm.texi (TARGET_GEN_CCMP_FIRST, TARGET_GEN_CCMP_NEXT): Update
parameters.
* target.def (gen_ccmp_first, gen_ccmp_next): Update parameters.

testsuite/ChangeLog:
2014-12-12  Zhenqiang Chen  zhenqiang.c...@arm.com

* gcc.dg/pr64015.c: New test.


gen-ccmp.patch
Description: Binary data


Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2014-11-28 Thread Richard Henderson
On 11/26/2014 10:23 AM, Zhenqiang Chen wrote:
   /* Check to make sure CC is not clobbered since prepare_operand might
  generates copy or mode convertion insns, although no test shows
  such insns clobber CC.  */

And what do you do if a clobber does happen?
With TER enabled, there's every possibility that it might be.

 Does such change align with your comments?

Not really, no.


r~



RE: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2014-11-26 Thread Zhenqiang Chen


 -Original Message-
 From: Richard Henderson [mailto:r...@redhat.com]
 Sent: Tuesday, November 25, 2014 5:25 PM
 To: Zhenqiang Chen
 Cc: Marcus Shawcroft; gcc-patches@gcc.gnu.org
 Subject: Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)
 
 On 11/25/2014 09:41 AM, Zhenqiang Chen wrote:
  I want to confirm with you two things before I rework it.
  (1) expand_insn needs an optab_handler as input. Do I need to define a
 ccmp_optab with different mode support in optabs.def?
 
 No, look again: expand_insn needs an enum insn_code as input.  Since this is
 the backend, you can use any icode name you like, which means that you can
 use CODE_FOR_ccmp_and etc directly.
 
  (2) To make sure later operands not clobber CC, all operands are expanded
 before ccmp-first in current implementation. If taking tree/gimple as input,
 what's your preferred logic to guarantee CC not clobbered?
 
 Hmm.  Perhaps the target hook will need to output two sequences, each of
 which will be concatenated while looping around the calls to gen_ccmp_next.
 The first sequence will be operand preparation and the second sequence will
 be ccmp generation.
 
 Something like
 
 bool
 aarch64_gen_ccmp_start(rtx *prep_seq, rtx *gen_seq,
int cmp_code, int bit_code,
tree op0, tree op1) {
   bool success;
 
   start_sequence ();
   // Widen and expand operands
   *prep_seq = get_insns ();
   end_sequence ();
 
   start_sequence ();
   // Generate the first compare
   *gen_seq = get_insns ();
   end_sequence ();
 
   return success;
 }
 
 bool
 aarch64_gen_ccmp_next(rtx *prep_seq, rtx *gen_seq,
   rtx prev, int cmp_code, int bit_code,
   tree op0, tree op1) {
   bool success;
 
   push_to_sequence (*prep_seq);
   // Widen and expand operands
   *prep_seq = get_insns ();
   end_sequence ();
 
   push_to_sequence (*gen_seq);
   // Generate the next ccmp
   *gen_seq = get_insns ();
   end_sequence ();
 
   return success;
 }
 
 If there are ever any failures, the middle-end can simply discard the
 sequences.  If everything succeeds, it simply calls emit_insn on both
 sequences.

When there are more than one ccmps, it will be complexity to maintain the 
un-emitted sequences in a recursive algorithm. E.g.
 CC0 = CMP (a, b);
 CC1 = CCMP (NE (CC0, 0), CMP (e, f));
 ...
 CCn = CCMP (NE (CCn-1, 0), CMP (...));

I read the codes to expand cstoresi and cbranchsi. It just uses normal 
expand_operands. So I think we can keep expand_operands in middle-end.

For the start one, we do not need worry about it since its last step should 
compare to set CC. And it is easy to delete the insns when fail.
static rtx
aarch64_gen_ccmp_first (int code, rtx op0, rtx op1)
{
   ...  // init the vars

  op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode, unsignedp);
  op1 = prepare_operand (icode, op1, 3, op_mode, cmp_mode, unsignedp);
  if (!op0 || !op1)
return NULL_RTX;

  cmp = gen_rtx_fmt_ee ((enum rtx_code) code, cmp_mode, op0, op1);
  target = gen_rtx_REG (CCmode, CC_REGNUM);

  create_output_operand (ops[0], target, CCmode);
  create_fixed_operand (ops[1], cmp);
  create_fixed_operand (ops[2], op0);
  create_fixed_operand (ops[3], op1);

  if (!maybe_expand_insn (icode, 4, ops))
return NULL_RTX;

  return gen_rtx_REG (cc_mode, CC_REGNUM);
}

aarch64_gen_ccmp_next (rtx prev, int cmp_code, rtx op0, rtx op1, int bit_code)
{
   ...  // init the vars

  op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode, unsignedp);
  op1 = prepare_operand (icode, op1, 3, op_mode, cmp_mode, unsignedp);
  if (!op0 || !op1)
return NULL_RTX;

  /* Check to make sure CC is not clobbered since prepare_operand might
 generates copy or mode convertion insns, although no test shows
 such insns clobber CC.  */
  ...

  cmp1 = gen_rtx_fmt_ee ((enum rtx_code) cmp_code, cmp_mode, op0, op1);
  cmp0 = gen_rtx_fmt_ee (NE, cmp_mode, prev, const0_rtx);

  target = gen_rtx_REG (cc_mode, CC_REGNUM);

  create_fixed_operand (ops[0], prev);
  create_fixed_operand (ops[1], target);
  create_fixed_operand (ops[2], op0);
  create_fixed_operand (ops[3], op1);
  create_fixed_operand (ops[4], cmp0);
  create_fixed_operand (ops[5], cmp1);

  if (!maybe_expand_insn (icode, 6, ops))
return NULL_RTX;

  return target;
}

Does such change align with your comments?

Thanks!
-Zhenqiang





RE: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2014-11-25 Thread Zhenqiang Chen


 -Original Message-
 From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
 ow...@gcc.gnu.org] On Behalf Of Richard Henderson
 Sent: Monday, November 24, 2014 4:57 PM
 To: Zhenqiang Chen; gcc-patches@gcc.gnu.org
 Cc: Marcus Shawcroft
 Subject: Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)
 
 On 11/24/2014 06:11 AM, Zhenqiang Chen wrote:
  Expand pass always uses sign-extend to represent constant value. For
  the case in the patch, a 8-bit unsigned value 252 is represented as
  -4, which pass the ccmn check. After mode conversion, -4 becomes
  252, which leads to mismatch.
 
 This sort of thing is why I suggested from the beginning that expansion
 happen directly from trees instead of sort-of re-expanding from rtl.
 
 I think you're better off fixing this properly than hacking around it here.

Thanks for the comments.

Here was your previous comments: We could avoid that by using struct 
expand_operand, create_input_operand et al, then expand_insn.  That does 
require that the target hooks be given trees rather than rtl as input.

I want to confirm with you two things before I rework it.
(1) expand_insn needs an optab_handler as input. Do I need to define a 
ccmp_optab with different mode support in optabs.def?
(2) To make sure later operands not clobber CC, all operands are expanded 
before ccmp-first in current implementation. If taking tree/gimple as input, 
what's your preferred logic to guarantee CC not clobbered?

Thanks!
-Zhenqiang





Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2014-11-25 Thread Richard Henderson
On 11/25/2014 09:41 AM, Zhenqiang Chen wrote:
 I want to confirm with you two things before I rework it.
 (1) expand_insn needs an optab_handler as input. Do I need to define a 
 ccmp_optab with different mode support in optabs.def?

No, look again: expand_insn needs an enum insn_code as input.  Since this is
the backend, you can use any icode name you like, which means that you can use
CODE_FOR_ccmp_and etc directly.

 (2) To make sure later operands not clobber CC, all operands are expanded 
 before ccmp-first in current implementation. If taking tree/gimple as input, 
 what's your preferred logic to guarantee CC not clobbered?

Hmm.  Perhaps the target hook will need to output two sequences, each of which
will be concatenated while looping around the calls to gen_ccmp_next.  The
first sequence will be operand preparation and the second sequence will be ccmp
generation.

Something like

bool
aarch64_gen_ccmp_start(rtx *prep_seq, rtx *gen_seq,
   int cmp_code, int bit_code,
   tree op0, tree op1)
{
  bool success;

  start_sequence ();
  // Widen and expand operands
  *prep_seq = get_insns ();
  end_sequence ();

  start_sequence ();
  // Generate the first compare
  *gen_seq = get_insns ();
  end_sequence ();

  return success;
}

bool
aarch64_gen_ccmp_next(rtx *prep_seq, rtx *gen_seq,
  rtx prev, int cmp_code, int bit_code,
  tree op0, tree op1)
{
  bool success;

  push_to_sequence (*prep_seq);
  // Widen and expand operands
  *prep_seq = get_insns ();
  end_sequence ();

  push_to_sequence (*gen_seq);
  // Generate the next ccmp
  *gen_seq = get_insns ();
  end_sequence ();

  return success;
}

If there are ever any failures, the middle-end can simply discard the
sequences.  If everything succeeds, it simply calls emit_insn on both sequences.


r~


Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2014-11-24 Thread Richard Henderson
On 11/24/2014 06:11 AM, Zhenqiang Chen wrote:
 Expand pass always uses sign-extend to represent constant value. For the
 case in the patch, a 8-bit unsigned value 252 is represented as -4,
 which pass the ccmn check. After mode conversion, -4 becomes 252, which
 leads to mismatch.

This sort of thing is why I suggested from the beginning that expansion
happen directly from trees instead of sort-of re-expanding from rtl.

I think you're better off fixing this properly than hacking around it here.


r~


Re: [PATCH, AARCH64] Fix ICE in CCMP (PR64015)

2014-11-23 Thread Andrew Pinski
On Sun, Nov 23, 2014 at 9:11 PM, Zhenqiang Chen zhenqiang.c...@arm.com wrote:
 Hi,

 Expand pass always uses sign-extend to represent constant value. For the
 case in the patch, a 8-bit unsigned value 252 is represented as -4,
 which pass the ccmn check. After mode conversion, -4 becomes 252, which
 leads to mismatch.

 The patch adds another operand check after mode conversion.

 No make check regression with qemu.

 OK for trunk?

 Thanks!
 -Zhenqiang

 ChangeLog:
 2014-11-24  Zhenqiang Chen  zhenqiang.c...@arm.com

 PR target/64015
 * config/aarch64/aarch64.c (aarch64_gen_ccmp_first): Recheck operand
 after mode conversion.
 (aarch64_gen_ccmp_next): Likewise.

 testsuite/ChangeLog:
 2014-11-24  Zhenqiang Chen  zhenqiang.c...@arm.com

 * gcc.target/aarch64/pr64015.c: New test.

 diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
 index 1809513..203d095 100644
 --- a/gcc/config/aarch64/aarch64.c
 +++ b/gcc/config/aarch64/aarch64.c
 @@ -10311,7 +10311,10 @@ aarch64_gen_ccmp_first (int code, rtx op0, rtx op1)
if (!aarch64_plus_operand (op1, GET_MODE (op1)))
  op1 = force_reg (mode, op1);

 -  if (!aarch64_convert_mode (op0, op1, unsignedp))
 +  if (!aarch64_convert_mode (op0, op1, unsignedp)
 +/* Some negative value might be transformed into a positive one.
 +   So need recheck here.  */
 +  || !aarch64_plus_operand (op1, GET_MODE (op1)))
  return NULL_RTX;

Shouldn't we force it to a reg here instead?


mode = aarch64_code_to_ccmode ((enum rtx_code) code);
 @@ -10344,7 +10347,10 @@ aarch64_gen_ccmp_next (rtx prev, int cmp_code, rtx
 op0, rtx op1, int bit_code)
|| !aarch64_ccmp_operand (op1, GET_MODE (op1)))
  return NULL_RTX;

 -  if (!aarch64_convert_mode (op0, op1, unsignedp))
 +  if (!aarch64_convert_mode (op0, op1, unsignedp)
 +/* Some negative value might be transformed into a positive one.
 +   So need recheck here.  */
 +  || !aarch64_ccmp_operand (op1, GET_MODE (op1)))
  return NULL_RTX;


Also really the cost of forcing to a register is better really.
In the cases where we would not have forced to a register in a cmp
instruction, the constant would be one instruction and compared to the
cost of two cset and an and/or is better.
In the cases where we would have forced to a register for the cmp
instruction, two cost for doing the forcing is the same on both cases
but since we gaining from removing a cset and an and/or we are better.


mode = aarch64_code_to_ccmode ((enum rtx_code) cmp_code);

 diff --git a/gcc/testsuite/gcc.target/aarch64/pr64015.c
 b/gcc/testsuite/gcc.target/aarch64/pr64015.c
 new file mode 100644
 index 000..eeed665
 --- /dev/null
 +++ b/gcc/testsuite/gcc.target/aarch64/pr64015.c
 @@ -0,0 +1,7 @@
 +/* { dg-do compile } */
 +/* { dg-options  -O2  } */
 +int
 +test (unsigned short a, unsigned char b)
 +{
 +  return a  0xfff2  b  252;
 +}

Since this testcase is generic (except for the -O2), it really should
go into gcc.c-torture/compile instead of remove the two dg-*
directives so it can be tested on more than AARCH64 and on more
optimization levels.


Thanks,
Andrew Pinski