Bug 97255 - [8 Regression] Vectorizer gives a boolean a value of 255
Summary: [8 Regression] Vectorizer gives a boolean a value of 255
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 10.2.0
: P2 normal
Target Milestone: 8.5
Assignee: Richard Biener
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2020-09-30 12:45 UTC by Iwan Smith
Modified: 2023-02-25 00:32 UTC (History)
3 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, 8.4.0, 9.3.0
Last reconfirmed: 2020-09-30 00:00:00


Attachments
Minimal file demonstrating bug (382 bytes, text/plain)
2020-09-30 12:45 UTC, Iwan Smith
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Iwan Smith 2020-09-30 12:45:08 UTC
Created attachment 49292 [details]
Minimal file demonstrating bug

Here is a godbolt link demonstrating the bug: https://godbolt.org/z/jK8Wsz

The following function with -O3 assigns a value of 255 to variables in the out array. Building with -O3 -fno-tree-vectorize allows the code to execute correctly 

void
logicalOr(Array< char, 4 > in1[60], 
    Array< bool, 4 > out[60])
{
    for (unsigned k0 = 0u; k0 < 60u; ++k0) {
        Array< char, 4 > in1m = in1[k0];
        Array< bool, 4 > x;
        for (unsigned k1 = 0u; k1 < 4u; ++k1) {
            char in1s = in1m[k1];
            x[k1] = in1s != char(0) || in1s != char(0);
        }
        out[k0] = x;
    }
}


build the attached cpp file (it has no #includes) with 

(Buggy)
gcc -O3 vectorizedBool.cpp
./a.out
echo $? // correct value is 1. Actually returns 255

(Not buggy)
gcc -O3 -fno-tree-vectorize vectorizedBool.cpp 
./a.out
echo $? // correct value is 1. returns 1

Here is some output from -v

COLLECT_GCC=/opt/compiler-explorer/gcc-10.2.0/bin/g++

Target: x86_64-linux-gnu

Configured with: ../gcc-10.2.0/configure --prefix=/opt/compiler-explorer/gcc-build/staging --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --disable-bootstrap --enable-multiarch --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --enable-clocale=gnu --enable-languages=c,c++,fortran,ada,go,d --enable-ld=yes --enable-gold=yes --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-linker-build-id --enable-lto --enable-plugins --enable-threads=posix --with-pkgversion=Compiler-Explorer-Build

Thread model: posix

Supported LTO compression algorithms: zlib

gcc version 10.2.0 (Compiler-Explorer-Build) 

COLLECT_GCC_OPTIONS='-fdiagnostics-color=always' '-g' '-o' './output.s' '-masm=intel' '-S' '-v' '-O3' '-g' '-Wall' '-Wextra' '-fno-strict-aliasing' '-fwrapv' '-fno-aggressive-loop-optimizations' '-shared-libgcc' '-mtune=generic' '-march=x86-64'

 /opt/compiler-explorer/gcc-10.2.0/bin/../libexec/gcc/x86_64-linux-gnu/10.2.0/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -iprefix /opt/compiler-explorer/gcc-10.2.0/bin/../lib/gcc/x86_64-linux-gnu/10.2.0/ -D_GNU_SOURCE <source> -quiet -dumpbase example.cpp -masm=intel -mtune=generic -march=x86-64 -auxbase-strip ./output.s -g -g -O3 -Wall -Wextra -version -fdiagnostics-color=always -fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations -o ./output.s

GNU C++14 (Compiler-Explorer-Build) version 10.2.0 (x86_64-linux-gnu)

	compiled by GNU C version 7.5.0, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version isl-0.18-GMP



GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Comment 1 Martin Liška 2020-09-30 14:12:50 UTC
Confirmed, started with r7-717-geb09cdcb1a8b55b9.
Comment 2 Richard Biener 2020-09-30 15:01:42 UTC
I will have a look.
Comment 3 Richard Biener 2020-10-01 07:24:22 UTC
OK, so it's SRA that creates the IL that ultimatively confuses the vectorizer.
SRA transforms the bool accesses into unsigned char ones:

   _32 = in1s_31 != 0;
-  MEM <struct Array> [(bool &)&x].m_arr[1] = _32;
+  _7 = VIEW_CONVERT_EXPR<unsigned char>(_32);
+  x$1_16 = _7;
...
   _5 = out_17(D) + _2;
-  *_5 = x;
+  MEM <unsigned char> [(struct Array *)_5] = x_15;
+  MEM <unsigned char> [(struct Array *)_5 + 1B] = x$1_16;
+  MEM <unsigned char> [(struct Array *)_5 + 2B] = x$2_23;
+  MEM <unsigned char> [(struct Array *)_5 + 3B] = x$3_28;

we do not recognize the VIEW_CONVERT_EXPR as bool pattern.  I have a fix.
Comment 4 Richard Biener 2020-10-01 10:36:31 UTC
commit 36e691d3a62145fda1f4a1b3143d215cc113c10a (origin/master, origin/HEAD)
Author: Richard Biener <rguenther@suse.de>
Date:   Thu Oct 1 09:29:32 2020 +0200

    tree-optimization/97255 - missing vector bool pattern of SRAed bool
    
    SRA tends to use VIEW_CONVERT_EXPR when replacing bool fields with
    unsigned char fields.  Those are not handled in vector bool pattern
    detection causing vector true values to leak.  The following fixes
    this by turning those into b ? 1 : 0 as well.
    
    2020-10-01  Richard Biener  <rguenther@suse.de>
    
            * tree-vect-patterns.c (vect_recog_bool_pattern): Also handle
            VIEW_CONVERT_EXPR.
    
            * g++.dg/vect/pr97255.cc: New testcase.
Comment 5 GCC Commits 2020-10-12 08:28:14 UTC
The releases/gcc-10 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:67baa11f68e72cf562c491a8107bcdf3f1d6fc9b

commit r10-8878-g67baa11f68e72cf562c491a8107bcdf3f1d6fc9b
Author: Richard Biener <rguenther@suse.de>
Date:   Thu Oct 1 09:29:32 2020 +0200

    tree-optimization/97255 - missing vector bool pattern of SRAed bool
    
    SRA tends to use VIEW_CONVERT_EXPR when replacing bool fields with
    unsigned char fields.  Those are not handled in vector bool pattern
    detection causing vector true values to leak.  The following fixes
    this by turning those into b ? 1 : 0 as well.
    
    2020-10-01  Richard Biener  <rguenther@suse.de>
    
            PR tree-optimization/97255
            * tree-vect-patterns.c (vect_recog_bool_pattern): Also handle
            VIEW_CONVERT_EXPR.
    
            * g++.dg/vect/pr97255.cc: New testcase.
Comment 6 GCC Commits 2020-12-02 12:21:37 UTC
The releases/gcc-9 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

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

commit r9-9091-gf720a0d776252aac3002a0a9307a96465f1975bd
Author: Richard Biener <rguenther@suse.de>
Date:   Thu Oct 1 09:29:32 2020 +0200

    tree-optimization/97255 - missing vector bool pattern of SRAed bool
    
    SRA tends to use VIEW_CONVERT_EXPR when replacing bool fields with
    unsigned char fields.  Those are not handled in vector bool pattern
    detection causing vector true values to leak.  The following fixes
    this by turning those into b ? 1 : 0 as well.
    
    2020-10-01  Richard Biener  <rguenther@suse.de>
    
            PR tree-optimization/97255
            * tree-vect-patterns.c (vect_recog_bool_pattern): Also handle
            VIEW_CONVERT_EXPR.
    
            * g++.dg/vect/pr97255.cc: New testcase.
    
    (cherry picked from commit 36e691d3a62145fda1f4a1b3143d215cc113c10a)
Comment 7 GCC Commits 2021-03-17 11:14:21 UTC
The releases/gcc-8 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:87da0caaec663bd427147c04e5784d7843ede96a

commit r8-10806-g87da0caaec663bd427147c04e5784d7843ede96a
Author: Richard Biener <rguenther@suse.de>
Date:   Thu Oct 1 09:29:32 2020 +0200

    tree-optimization/97255 - missing vector bool pattern of SRAed bool
    
    SRA tends to use VIEW_CONVERT_EXPR when replacing bool fields with
    unsigned char fields.  Those are not handled in vector bool pattern
    detection causing vector true values to leak.  The following fixes
    this by turning those into b ? 1 : 0 as well.
    
    2020-10-01  Richard Biener  <rguenther@suse.de>
    
            PR tree-optimization/97255
            * tree-vect-patterns.c (vect_recog_bool_pattern): Also handle
            VIEW_CONVERT_EXPR.
    
            * g++.dg/vect/pr97255.cc: New testcase.
    
    (cherry picked from commit f720a0d776252aac3002a0a9307a96465f1975bd)
Comment 8 Richard Biener 2021-03-17 11:16:36 UTC
Fixed.