Bug 117271 - [13/14/15 regression] GCC trunk emits larger code at -Os than 12.4.0 since r14-3084-gaadc5c07feb0ab
Summary: [13/14/15 regression] GCC trunk emits larger code at -Os than 12.4.0 since r1...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 15.0
: P3 normal
Target Milestone: 13.4
Assignee: Not yet assigned to anyone
URL:
Keywords: code-size, missed-optimization
Depends on:
Blocks: VRP
  Show dependency treegraph
 
Reported: 2024-10-23 09:47 UTC by Davide Italiano
Modified: 2024-11-15 09:08 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 12.4.1
Known to fail: 13.3.1, 14.2.1, 15.0
Last reconfirmed: 2024-11-15 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Davide Italiano 2024-10-23 09:47:56 UTC
Testcase (-Os):

int f(int* a) {
  if (*a > 5 && ((*a % 2 == 0 && *a < 20) || (*a > 10 && *a % 3 != 0))) { 
    *a = *a * 2;
  }
  int arr[5];
  for (int i = 0; i < 5; i++) {
    arr[i] = *a + i;
  }
  for (int j = 0; j < 3; j++) {
    for (int k = 0; k < 2 && arr[j] % 2 == 0; k++) {
      arr[j] += k * 2;
    }
  }

  int sum = 0;
  for (int m = 0; m < 5 && (arr[m] % 3 == 0 || arr[m] > 10); m++) {
    sum += arr[m] * (m % 2 == 0 ? 2 : 3);
    for (int n = 0; n < 2 && (sum % 2 != 0 || m > 2); n++) {
      sum -= n * (m % 2 == 0 ? 1 : 2);
      if (n > 0 && sum > 10 && (arr[m] % 2 != 0 || m < 3)) {
        sum += arr[m] / 2;
      }
    }
    if (sum > 20 && m > 1) {
      sum *= 2;
    }
  }
  arr[0] += sum;

  return arr[0];
}


Bisects to:

commit aadc5c07feb0ab08729ab25d0d896b55860ad9e6                                            
Author: Andrew Pinski <apinski@marvell.com>                                                                                                                                           
Date:   Mon Aug 7 00:05:21 2023 -0700                                                                                                                                                 
                                                                                                                                                                                      
    VR-VALUES [PR28794]: optimize compare assignments also                                                                                                                            
                                                                                                                                                                                      
    This patch fixes the oldish (2006) bug where VRP was not                                                                                                                          
    optimizing the comparison for assignments while handling                                                                                                                          
    them for GIMPLE_COND only.                                                             
    It just happens to also solves PR 103281 due to allowing                               
    to optimize `c < 1` to `c == 0` and then we get                                        
    `(c == 0) == c` (which was handled by r14-2501-g285c9d04).                             
                                                                                           
    OK? Bootstrapped and tested on x86_64-linux-gnu with no                                
    regressions.                                                                           
                                             
            PR tree-optimization/103281      
            PR tree-optimization/28794                                                     
                                             
    gcc/ChangeLog:                           
                                             
            * vr-values.cc (simplify_using_ranges::simplify_cond_using_ranges_1): Split out
            majority to ...                                                                
            (simplify_using_ranges::simplify_compare_using_ranges_1): Here.                
            (simplify_using_ranges::simplify_casted_cond): Rename to ...                   
            (simplify_using_ranges::simplify_casted_compare): This                         
            and change arguments to take op0 and op1.                                      
            (simplify_using_ranges::simplify_compare_assign_using_ranges_1): New method.   
            (simplify_using_ranges::simplify): For tcc_comparison assignments call         
            simplify_compare_assign_using_ranges_1.                                        
            * vr-values.h (simplify_using_ranges): Add                                     
            new methods, simplify_compare_using_ranges_1 and simplify_compare_assign_using_ranges_1.
            Rename simplify_casted_cond and simplify_casted_compare and                    
            update argument types.                                                         
                                             
    gcc/testsuite/ChangeLog:                                                               
                                             
            * gcc.dg/tree-ssa/pr103281-1.c: New test.                                      
            * gcc.dg/tree-ssa/vrp-compare-1.c: New test.                                   

 gcc/testsuite/gcc.dg/tree-ssa/pr103281-1.c    |  19 +++                                   
 gcc/testsuite/gcc.dg/tree-ssa/vrp-compare-1.c |  13 +++                                   
 gcc/vr-values.cc                              | 160 ++++++++++++++++----------            
 gcc/vr-values.h                               |   4 +-                                    
 4 files changed, 134 insertions(+), 62 deletions(-)                                       
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr103281-1.c                             
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-compare-1.c
Comment 1 Davide Italiano 2024-10-23 09:50:04 UTC
https://godbolt.org/z/eExfPsjzs
Comment 2 Andrew Pinski 2024-10-23 17:41:09 UTC
Global Exported: _40 = [irange] int [-2, 2]
Global Exported: _71 = [irange] int [0, 1] MASK 0x1 VALUE 0x0
Global Exported: iftmp.0_53 = [irange] int [2, 3] MASK 0x1 VALUE 0x2
Global Exported: n_52 = [irange] int [0, 2]
Simplified relational if (n_52 <= 1)
 into if (n_52 != 2)

Global Exported: _70 = [irange] int [0, 1] MASK 0x1 VALUE 0x0
Global Exported: iftmp.2_54 = [irange] int [1, 2] MASK 0x3 VALUE 0x0
Global Exported: _25 = [irange] int [0, 2]
Simplified relational _26 = n_52 > 0;
 into _26 = n_52 == 1;

It is the second one which causes the issue. But that has so many things down the line.