Bug 78559 - [7 Regression] wrong code due to tree if-conversion?
Summary: [7 Regression] wrong code due to tree if-conversion?
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 7.0
: P1 normal
Target Milestone: 7.0
Assignee: Bernd Schmidt
URL:
Keywords: wrong-code
: 98269 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-11-28 10:07 UTC by ktkachov
Modified: 2020-12-15 12:01 UTC (History)
6 users (show)

See Also:
Host:
Target: aarch64
Build:
Known to work: 6.2.1
Known to fail: 7.0
Last reconfirmed: 2017-01-24 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description ktkachov 2016-11-28 10:07:02 UTC
The testcase:
int g = 20;
int d = 0;
 
short
fn2 (int p1, int p2)
{
  return p2 >= 2 || 5 >> p2 ? p1 : p1 << p2;
}
 
int
main ()
{
  int result = 0;
lbl_2582:
  if (g)
    {
      for (int c = -3; c; c++)
        result = fn2 (1, g);
    }
  else
    {
      for (int i = 0; i < 2; i += 2)
        if (d)
          goto lbl_2582;
    }
  if (result != 1)
    __builtin_abort ();
  return 0;
}


used to (erroneously) abort on aarch64-none-linux-gnu with -O3 after r235808 but stopped aborting with r242550. It still passes after the fix r242689 but I'm not sure if the bug has just gone latent.

To reproduce on aarch64 you'll have to revert r242689 and r242550.
Comment 1 bin cheng 2016-11-28 10:18:39 UTC
Thanks for reporting.  I will investigate.
Comment 2 Richard Biener 2016-11-28 12:06:56 UTC
Should reproduce still with -ftree-loop-if-convert after r242550?
Comment 3 ktkachov 2016-11-28 12:09:26 UTC
(In reply to Richard Biener from comment #2)
> Should reproduce still with -ftree-loop-if-convert after r242550?

Yes it does with 242837. Thanks
Comment 4 bin cheng 2016-11-30 17:03:11 UTC
I think it's a combine issue reveal by that change.  I am testing a patch for public discussion, guess Segher may have better solutions.
Comment 5 bin cheng 2016-12-01 09:50:16 UTC
(insn 37 35 39 7 (set (reg:SI 96)
        (sign_extend:SI (subreg:QI (reg:SI 95) 0))) 86 {*extendqisi2_aarch64}
     (expr_list:REG_DEAD (reg:SI 95)
        (nil)))
(insn 39 37 40 7 (set (reg:CC 66 cc)
        (compare:CC (reg:SI 96)
            (const_int 0 [0]))) 392 {cmpsi}
     (expr_list:REG_DEAD (reg:SI 96)
        (nil)))
(insn 40 39 41 7 (set (reg:HI 93)
        (if_then_else:HI (ne (reg:CC 66 cc)
                (const_int 0 [0]))
            (subreg/s/u:HI (reg:SI 81 [ iftmp.0_17 ]) 0)
            (reg:HI 97))) 443 {*cmovhi_insn}
     (expr_list:REG_DEAD (reg:CC 66 cc)
        (expr_list:REG_EQUAL (if_then_else:HI (ne (reg:CC 66 cc)
                    (const_int 0 [0]))
                (subreg/s/u:HI (reg:SI 81 [ iftmp.0_17 ]) 0)
                (const_int 1 [0x1]))
            (nil))))

-------------->
Trying 37 -> 39:
Failed to match this instruction:
(set (reg:CC 66 cc)
    (reg:CC 66 cc))
Successfully matched this instruction:
(set (reg:HI 93)
    (if_then_else:HI (le (reg:CC 66 cc)
            (const_int 0 [0]))
        (subreg/s/u:HI (reg:SI 81 [ iftmp.0_17 ]) 0)
        (reg:HI 97)))
allowing combination of insns 37 and 39
original costs 4 + 4 = 12
replacement cost 8
deferring deletion of insn with uid = 37.
modifying other_insn    40: r93:HI={(cc:CC<=0)?r81:SI#0:r97:HI}
      REG_DEAD cc:CC
      REG_EQUAL {(cc:CC!=0)?r81:SI#0:0x1}
deferring rescan insn with uid = 40.
modifying insn i3    39: cc:CC=cc:CC
deferring rescan insn with uid = 39.

Note after combine:
40: r93:HI={(cc:CC<=0)?r81:SI#0:r97:HI}
      REG_DEAD cc:CC
      REG_EQUAL {(cc:CC!=0)?r81:SI#0:0x1}
cc register has been changed, and (cc<=0) != (cc!=0).
Comment 6 Jakub Jelinek 2016-12-13 10:19:23 UTC
So do you think combiner should throw away the REG_EQUAL note in that case, or something different?
Comment 7 bin cheng 2017-01-13 10:19:59 UTC
(In reply to Jakub Jelinek from comment #6)
> So do you think combiner should throw away the REG_EQUAL note in that case,
> or something different?

It's invalid after transformation, so should be discarded in this case.  What I am not sure is that how to tell invalid ones from all notes and keep others.  I sent a proposed patch for discussion before @https://gcc.gnu.org/ml/gcc-patches/2016-12/msg00026.html

Thanks.
Comment 8 Jeffrey A. Law 2017-01-24 23:31:51 UTC
Bernd.  There's a belief this may be a combiner issue, so it might be something you'd want to poke at.

I can still trigger this failure on the trunk using -ftree-loop-if-convert on an aarch64 native.  If you need access to an aarch64 system, let me know, I've got one provisioned.
Comment 9 Bernd Schmidt 2017-01-24 23:36:18 UTC
Ok, I'll look.
Comment 10 Segher Boessenkool 2017-01-25 04:20:58 UTC
I am leaning toward accepting Bin's patch, but testing whether that hurts
generated code too much still hasn't finished.
Comment 11 Bernd Schmidt 2017-01-25 14:40:22 UTC
Looks like other_insn is only used for cases where we rewrite cc sets in this way, so Bin's patch does look reasonably narrow. We could maybe record the CC reg being changed and only discard reg notes, but in my testing I've not been able to produce code generation differences except for the testcase. Let's wait for Segher's testing, but I think the patch is OK.
Comment 12 Bernd Schmidt 2017-01-25 14:41:48 UTC
Sorry, long pause while editing that comment made me leave out part of what I was trying to say - I meant only discard notes that reference the CC reg. But it seems an unnecessary complication.
Comment 13 bin cheng 2017-01-27 14:42:55 UTC
Author: amker
Date: Fri Jan 27 14:42:23 2017
New Revision: 244979

URL: https://gcc.gnu.org/viewcvs?rev=244979&root=gcc&view=rev
Log:
	PR rtl-optimization/78559
	* combine.c (try_combine): Discard REG_EQUAL and REG_EQUIV for
	other_insn in combine.

	gcc/testsuite
	PR rtl-optimization/78559
	* gcc.c-torture/execute/pr78559.c: New test.

Added:
    trunk/gcc/testsuite/gcc.c-torture/execute/pr78559.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
    trunk/gcc/testsuite/ChangeLog
Comment 14 Jeffrey A. Law 2017-01-27 16:44:23 UTC
Fixed by Bin's patch on the trunk.
Comment 15 Andreas Krebbel 2020-12-15 12:01:51 UTC
*** Bug 98269 has been marked as a duplicate of this bug. ***