Bug 106687 - [13 Regression] Wrong code with -O2 since r13-438-gcf2141a0c640fc9b
Summary: [13 Regression] Wrong code with -O2 since r13-438-gcf2141a0c640fc9b
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 13.0
: P1 normal
Target Milestone: 13.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks: yarpgen
  Show dependency treegraph
 
Reported: 2022-08-19 15:54 UTC by Vsevolod Livinskii
Modified: 2022-08-23 01:06 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work: 12.0, 12.1.0
Known to fail: 13.0
Last reconfirmed: 2022-08-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vsevolod Livinskii 2022-08-19 15:54:07 UTC
Link to the Compiler Explorer: https://godbolt.org/z/a8PTr5sqM

The error disappears if I use another definition of max (b > p2 ? b : p2).

Reproducer:
#include <stdio.h>

bool var_0 = (bool)0;
unsigned int var_7 = 42;
char var_215;

const unsigned &a(const unsigned &b, unsigned &p2) { return b < p2 ? p2 : b; }
void test() { var_215 = a(var_0, var_7) ^ (var_7 - var_0) ?: 42; }

int main() {
  test();
  printf("%d\n", var_215);
  if (var_215 != 42)
    __builtin_abort();
}

Error:
>$ g++ -O1 small.cpp && ./a.out 
42
>$ g++ -O2 small.cpp && ./a.out 
0
Aborted (core dumped)

gcc version 13.0.0 20220819 (81e20a6eb9e6b7eb62a09ac58811387f0343bd14)
Comment 1 Drea Pinski 2022-08-19 16:12:07 UTC
Something more reduced:
bool var_0 = (bool)0;
unsigned int var_7 = 42;
char var_215;

int main() {
    unsigned b = var_0;
    unsigned p2 = var_7;
    unsigned *tp;
    if (b < p2)
      tp = &p2;
    else
      tp = &b;
    unsigned tt = *tp;
    unsigned t = tt ^ (var_7 - var_0);
    var_215 = t ? t : 42;
    if (var_215 != 42)
      __builtin_abort();
}
Comment 2 Martin Liška 2022-08-22 04:21:48 UTC
Started with r13-438-gcf2141a0c640fc9b.
Comment 3 GCC Commits 2022-08-23 01:05:35 UTC
The master branch has been updated by Andrew Macleod <amacleod@gcc.gnu.org>:

https://gcc.gnu.org/g:de6d9e0b3d5c08896cbf047b299fc7f8d1e42be7

commit r13-2147-gde6d9e0b3d5c08896cbf047b299fc7f8d1e42be7
Author: Andrew MacLeod <amacleod@redhat.com>
Date:   Mon Aug 22 15:40:48 2022 -0400

    Return the correct relation
    
    With an input condition of op1 > op2, and evaluating the unsigned expression:
    LHS = op1 - op2
    range-ops was returning LHS < op1 , which is incorrect as op2 coould be
    zero.  This patch adjusts it to return LHS <= op1.
    
            PR tree-optimization/106687
            gcc/
            * range-op.cc (operator_minus::lhs_op1_relation): Return VREL_LE
            for the VREL_GT case as well.
    
            gcc/testsuite/
            * g++.dg/pr106687.C: New.
Comment 4 Andrew Macleod 2022-08-23 01:06:59 UTC
fixed.