Bug 96369 - [8 Regression] Wrong evaluation order of || operator
Summary: [8 Regression] Wrong evaluation order of || operator
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 11.0
: P2 normal
Target Milestone: 8.5
Assignee: Richard Biener
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2020-07-29 14:14 UTC by Yu Zhige
Modified: 2024-07-18 08:07 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work: 10.2.1, 11.0, 8.4.1, 9.3.1
Known to fail: 10.2.0, 4.8.5, 7.5.0, 8.4.0, 9.3.0
Last reconfirmed: 2020-07-29 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Yu Zhige 2020-07-29 14:14:40 UTC
The following code snippet:

#include <stdio.h> 
int main(void)
{
    const long ONE = 1L;
    long y = 0L;
    long x = ((long) (ONE || (y = 1L)) % 8L);
    printf("x = %ld, y = %ld\n", x, y);    // with -O1/-O2/-O3 flag, gcc prints x = 1, y = 1 where clang prints x = 1, y = 0
}

> $ /usr/gcc-trunk/bin/gcc -O2 -Wall -Wextra bug.c -o a.out
> $ ./a.out
> x = 1, y = 1

If the first operand of a logical-OR operation has a nonzero value, the second operand is not evaluated. Therefore (y = 1L) should not be evaluated. It should print y = 0 instead of y = 1.

This bug appears in GCC-4.8, GCC-6.4.0, GCC-7.5.0, GCC-8.4.0, GCC-9.3.0, GCC-10.2.0 and GCC-11.0.0 20200501.
Comment 1 Richard Biener 2020-07-30 05:57:46 UTC
Works with -O0, already failed with -O1 in .original:

    long int x = y = 1;, 1;

works with the C++ frontend so a frontend specific "misoptimization".
Comment 2 Joseph S. Myers 2020-07-31 00:21:55 UTC
Actually it appears the wrong code is being introduced somewhere in fold_range_test (I didn't trace it further than that); the only front-end involvement is that the front end does folding as part of conversions at various points.

Testing with old compilers suggests this appeared between 4.8.1 and 4.8.3 (quite possibly through some backported change perturbing the exact sequence of calls to folding functions rather than the actual underlying cause being introduced in whatever backport).
Comment 3 Richard Biener 2020-07-31 06:39:30 UTC
I have a patch.
Comment 4 GCC Commits 2020-07-31 10:12:07 UTC
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:10231958fcfb13bc4847729eba21470c101b4a88

commit r11-2450-g10231958fcfb13bc4847729eba21470c101b4a88
Author: Richard Biener <rguenther@suse.de>
Date:   Fri Jul 31 08:41:56 2020 +0200

    middle-end/96369 - fix missed short-circuiting during range folding
    
    This makes the special case of constant evaluated LHS for a
    short-circuiting or/and explicit rather than doing range
    merging and eventually exposing a side-effect that shouldn't be
    evaluated.
    
    2020-07-31  Richard Biener  <rguenther@suse.de>
    
            PR middle-end/96369
            * fold-const.c (fold_range_test): Special-case constant
            LHS for short-circuiting operations.
    
            * c-c++-common/pr96369.c: New testcase.
Comment 5 Richard Biener 2020-07-31 10:12:44 UTC
Fixed on trunk sofar.
Comment 6 GCC Commits 2020-09-11 12:11:56 UTC
The releases/gcc-10 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

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

commit r10-8745-gd3a0ef7a523fb4cdeabfbb9fab56bfcf8d21ffd5
Author: Richard Biener <rguenther@suse.de>
Date:   Fri Jul 31 08:41:56 2020 +0200

    middle-end/96369 - fix missed short-circuiting during range folding
    
    This makes the special case of constant evaluated LHS for a
    short-circuiting or/and explicit rather than doing range
    merging and eventually exposing a side-effect that shouldn't be
    evaluated.
    
    2020-07-31  Richard Biener  <rguenther@suse.de>
    
            PR middle-end/96369
            * fold-const.c (fold_range_test): Special-case constant
            LHS for short-circuiting operations.
    
            * c-c++-common/pr96369.c: New testcase.
    
    (cherry picked from commit 10231958fcfb13bc4847729eba21470c101b4a88)
Comment 7 GCC Commits 2020-12-02 13:23:21 UTC
The releases/gcc-9 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:505767905735a3c8f171c140108ee263f9fdcad6

commit r9-9093-g505767905735a3c8f171c140108ee263f9fdcad6
Author: Richard Biener <rguenther@suse.de>
Date:   Fri Jul 31 08:41:56 2020 +0200

    middle-end/96369 - fix missed short-circuiting during range folding
    
    This makes the special case of constant evaluated LHS for a
    short-circuiting or/and explicit rather than doing range
    merging and eventually exposing a side-effect that shouldn't be
    evaluated.
    
    2020-07-31  Richard Biener  <rguenther@suse.de>
    
            PR middle-end/96369
            * fold-const.c (fold_range_test): Special-case constant
            LHS for short-circuiting operations.
    
            * c-c++-common/pr96369.c: New testcase.
    
    (cherry picked from commit 10231958fcfb13bc4847729eba21470c101b4a88)
Comment 8 GCC Commits 2021-03-17 11:14:05 UTC
The releases/gcc-8 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:371ae12cf3b22795246a5707017f07257b5cbc97

commit r8-10803-g371ae12cf3b22795246a5707017f07257b5cbc97
Author: Richard Biener <rguenther@suse.de>
Date:   Fri Jul 31 08:41:56 2020 +0200

    middle-end/96369 - fix missed short-circuiting during range folding
    
    This makes the special case of constant evaluated LHS for a
    short-circuiting or/and explicit rather than doing range
    merging and eventually exposing a side-effect that shouldn't be
    evaluated.
    
    2020-07-31  Richard Biener  <rguenther@suse.de>
    
            PR middle-end/96369
            * fold-const.c (fold_range_test): Special-case constant
            LHS for short-circuiting operations.
    
            * c-c++-common/pr96369.c: New testcase.
    
    (cherry picked from commit 505767905735a3c8f171c140108ee263f9fdcad6)
Comment 9 Richard Biener 2021-03-17 11:15:35 UTC
Fixed.
Comment 10 GCC Commits 2024-07-18 08:07:12 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

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

commit r15-2136-ge217e7dbdc1040e7ee160796e9ca1ef12a0dd1cb
Author: Sam James <sam@gentoo.org>
Date:   Thu Jul 18 10:00:17 2024 +0200

    testsuite: Add dg-do run to more tests
    
    All of these are for wrong-code bugs.  Confirmed to be used before but
    with no execution.
    
    2024-07-18  Sam James  <sam@gentoo.org>
    
            PR c++/53288
            PR c++/57437
            PR c/65345
            PR libstdc++/88101
            PR tree-optimization/96369
            PR tree-optimization/102124
            PR tree-optimization/108692
            * c-c++-common/pr96369.c: Add dg-do run directive.
            * gcc.dg/torture/pr102124.c: Ditto.
            * gcc.dg/pr108692.c: Ditto.
            * gcc.dg/atomic/pr65345-4.c: Ditto.
            * g++.dg/cpp0x/lambda/lambda-return1.C: Ditto.
            * g++.dg/init/lifetime4.C: Ditto.
            * g++.dg/torture/builtin-clear-padding-1.C: Ditto.
            * g++.dg/torture/builtin-clear-padding-2.C: Ditto.
            * g++.dg/torture/builtin-clear-padding-3.C: Ditto.
            * g++.dg/torture/builtin-clear-padding-4.C: Ditto.
            * g++.dg/torture/builtin-clear-padding-5.C: Ditto.