Bug 40141 - [4.3 Regression] accessing aliased __m128 miscompiles
Summary: [4.3 Regression] accessing aliased __m128 miscompiles
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.3.3
: P3 normal
Target Milestone: 4.4.0
Assignee: Richard Biener
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: alias, wrong-code
Depends on:
Blocks:
 
Reported: 2009-05-14 09:40 UTC by Matthias Kretz (Vir)
Modified: 2009-05-21 10:27 UTC (History)
1 user (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Known to work: 4.4.0
Known to fail: 4.3.3
Last reconfirmed: 2009-05-14 11:04:20


Attachments
patch (7.15 KB, patch)
2009-05-15 11:09 UTC, Richard Biener
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Kretz (Vir) 2009-05-14 09:40:23 UTC
Testcase:

#include <emmintrin.h>
#include <stdio.h>

typedef float floatA __attribute__((__may_alias__));

int main()
{
    __m128 x = _mm_setzero_ps();
    int i;
    for (i = 0; i < 4; ++i) {
        const float xx = ((floatA*)&x)[i];
        if (xx != 0.f) {
            printf("%d: %f\n", i, xx);
            return -1;
        }
    }
    return 0;
}

This fails with -O2, as well as with -O2 -fno-strict-aliasing. It works with -O1 and -O0.

The generated assembly shows that the stack is created but not initialized and then read from and checked whether it's 0.

If instead of
        const float xx = ((floatA*)&x)[i];
you write
        const float xx = ((floatA*)&x)[0];
(or any other constant between 0 and 3) then the testcase doesn't fail.

Tested versions:
4.2.4: doesn't fail
4.3.2: fails
4.3.3: fails
4.4.0: doesn't fail
Comment 1 Richard Biener 2009-05-14 11:04:19 UTC
Confirmed.  That's the SMTs do not include ref-all stuff bug so DCE removes
the initialization.

extern void abort (void);
typedef int __m128 __attribute__((vector_size(16), may_alias));
typedef float floatA __attribute__((may_alias));

int main()
{
  __m128 x = { 0, 0, 0, 0 };
  int i;
  for (i = 0; i < 4; ++i) {
      const float xx = ((floatA*)&x)[i];
      if (xx != 0.f)
        abort ();
  }
  return 0;
}

works without may_alias on __m128 for a strange reason.

I'll find the patch that fixed this.
Comment 2 Richard Biener 2009-05-14 14:50:23 UTC
For 4.4 this was fixed by

2008-04-29  Richard Guenther  <rguenther@suse.de>

        * tree-ssa-alias.c (finalize_ref_all_pointers): Remove.
        (compute_may_aliases): Do not call finalize_ref_all_pointers.
        (compute_flow_insensitive_aliasing): Do not treat
        PTR_IS_REF_ALL pointers special.
        (get_smt_for): Likewise.
        (may_alias_p): Re-structure.
        (is_escape_site): A ref-all pointer conversion is not an escape site.
        * tree-ssa-structalias.c (find_what_p_points_to): Do not treat
        PTR_IS_REF_ALL pointers special.
        * tree-ssa-structalias.h (struct alias_info): Remove
        ref_all_symbol_mem_tag field.
        (PTR_IS_REF_ALL): Remove.

eventually exposing PRs 38151 and 38246.  Which were fixed by

2008-11-25  Richard Guenther  <rguenther@suse.de>

        PR middle-end/38151
        PR middle-end/38236
        * tree-ssa-alias.c (struct alias_info): Remove written_vars.
        Remove dereferenced_ptrs_store and dereferenced_ptrs_load
        in favor of dereferenced_ptrs.
        (init_alias_info): Adjust.
        (delete_alias_info): Likewise.
        (compute_flow_insensitive_aliasing): Properly
        include all aliased variables.
        (update_alias_info_1): Use dereferenced_ptrs.
        (setup_pointers_and_addressables): Likewise.
        (get_smt_for): Honor ref-all pointers and pointers with known alias
        set properly.
        * config/i386/i386.c (ix86_gimplify_va_arg): Use ref-all pointers.
Comment 3 Richard Biener 2009-05-15 11:09:10 UTC
Created attachment 17873 [details]
patch

This is a patch backporting the fix and followups necessary to fix the fallout
(and the new testcases).
Comment 4 Richard Biener 2009-05-21 10:27:44 UTC
Patch was posted and rejected as too invasive for 4.3.  Distributors can apply
the referenced patch.

Thus, WONTFIX for 4.3, fixed for 4.4.