[Bug target/110598] [14 Regression] wrong code on llvm-14.0.6 due to memcmp being miscompiled

2023-07-08 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110598

Andrew Pinski  changed:

   What|Removed |Added

   Last reconfirmed||2023-07-08
 Status|UNCONFIRMED |NEW
   Target Milestone|--- |14.0
   Keywords||wrong-code
Summary|[14 Regression] wrong code  |[14 Regression] wrong code
   |on llvm-14.0.6  |on llvm-14.0.6 due to
   ||memcmp being miscompiled
 Ever confirmed|0   |1
  Component|c++ |target

--- Comment #1 from Andrew Pinski  ---
Confirmed looks like a target issue dealing with memcmp.
Take:
```

// $ cat bug.cpp
#include 

typedef unsigned long long u64;

const unsigned MAX_SUBTARGET_WORDS = 4;

[[gnu::noipa]]
int notequal(const void *a, const void *b)
{
return __builtin_memcmp(a,b,MAX_SUBTARGET_WORDS*sizeof(u64)) != 0;
}

struct FeatureBitset {
  u64 Bits[MAX_SUBTARGET_WORDS] = {0, 0, 0, 0};

  constexpr FeatureBitset() = default;
  constexpr FeatureBitset(std::initializer_list Init) {
for (auto I : Init) {
  Bits[I] = 1;
}
  }

  constexpr FeatureBitset operator&(const FeatureBitset &RHS) const {
FeatureBitset Result = *this;
for (unsigned I = 0, E = MAX_SUBTARGET_WORDS; I != E; ++I) {
  Result.Bits[I] &= RHS.Bits[I];
}
return Result;
  }

  bool operator!=(const FeatureBitset &RHS) const {
  return notequal(Bits, RHS.Bits);
  }
};

static constexpr const FeatureBitset TargetFeatures = { 0, 0, 0, 0, };

__attribute__((noipa))
bool is_eq_buggy (const FeatureBitset & lf, const FeatureBitset & rf) {
  if ((lf & TargetFeatures) != (rf & TargetFeatures))
return false;
  return true;
}

__attribute__((noipa))
void bug(void) {
FeatureBitset lf, rf;
lf.Bits[0] = rf.Bits[0] = 1;
lf.Bits[1] = rf.Bits[1] = 1;
lf.Bits[2] = rf.Bits[2] = 1;
lf.Bits[3] = rf.Bits[3] = 1;

bool r = is_eq_buggy (lf, rf);
if (!r) __builtin_trap();
}

__attribute__((noipa))
int main(void) {
bug();
}
```

The above is not miscompiled but once the gnu::noipa on the notequal is
removed, it is.

[Bug target/110598] [14 Regression] wrong code on llvm-14.0.6 due to memcmp being miscompiled

2023-07-08 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110598

--- Comment #2 from Andrew Pinski  ---
Here is a C testcase:
```
#include 

typedef unsigned long long u64;

#define MAX_SUBTARGET_WORDS 4

//[[gnu::noipa]]
int notequal(const void *a, const void *b)
{
return __builtin_memcmp(a,b,MAX_SUBTARGET_WORDS*sizeof(u64)) != 0;
}
typedef struct FeatureBitset {
  u64 Bits[MAX_SUBTARGET_WORDS];
}FeatureBitset;

__attribute__((noipa))
bool is_eq_buggy (const FeatureBitset * lf, const FeatureBitset * rf) {
u64 Bits_l[MAX_SUBTARGET_WORDS];
Bits_l[0] = lf->Bits[0]&1;
Bits_l[1] = 0;
Bits_l[2] = 0;
Bits_l[3] = 0;
u64 Bits_r[MAX_SUBTARGET_WORDS];
Bits_r[0] = rf->Bits[0]&1;
Bits_r[1] = 0;
Bits_r[2] = 0;
Bits_r[3] = 0;
return !notequal(Bits_l, Bits_r);
}

__attribute__((noipa))
void bug(void) {
FeatureBitset lf, rf;
lf.Bits[0] = rf.Bits[0] = 1;
lf.Bits[1] = rf.Bits[1] = 1;
lf.Bits[2] = rf.Bits[2] = 1;
lf.Bits[3] = rf.Bits[3] = 1;

bool r = is_eq_buggy (&lf, &rf);
if (!r) __builtin_trap();
}

__attribute__((noipa))
int main(void) {
bug();
}
```

Again uncomment the attribute on notequal, if you want to see it works without
inlining of memcmp here ...

[Bug target/110598] [14 Regression] wrong code on llvm-14.0.6 due to memcmp being miscompiled

2023-07-08 Thread slyfox at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110598

Sergei Trofimovich  changed:

   What|Removed |Added

 CC||roger at nextmovesoftware dot 
com

--- Comment #3 from Sergei Trofimovich  ---
git bisect landed on the r14-2087-g83269719640689 :

$ git bisect good
83269719640689415c0d5026ebfe05a0cf2bab72 is the first bad commit
commit 83269719640689415c0d5026ebfe05a0cf2bab72
Author: Roger Sayle 
Date:   Mon Jun 26 09:36:02 2023 +0100

i386: New *ashl_doubleword_highpart define_insn_and_split.

[Bug target/110598] [14 Regression] wrong code on llvm-14.0.6 due to memcmp being miscompiled

2023-07-09 Thread roger at nextmovesoftware dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110598

Roger Sayle  changed:

   What|Removed |Added

   Assignee|unassigned at gcc dot gnu.org  |roger at 
nextmovesoftware dot com
 Status|NEW |ASSIGNED

--- Comment #4 from Roger Sayle  ---
Mine.  The new peephole2 is misbehaving with the (odd) RTL sequence:
(insn 62 61 63 2 (set (reg:DI 1 dx [111])
(const_int 0 [0])) "pr110598.c":10:10 90 {*movdi_internal}

(insn 63 62 64 2 (parallel [
(set (reg:DI 1 dx [110])
(xor:DI (reg:DI 1 dx [111])
(reg:DI 1 dx)))
(clobber (reg:CC 17 flags))
]) "pr110598.c":10:10 626 {*xordi_1}
 (expr_list:REG_UNUSED (reg:CC 17 flags)
(nil)))

Doh!  I need to confirm/check that rega != regb.  Interesting that DF doesn't
consider insn 62 as REG_UNUSED (i.e. dead), a classic false dependency.

[Bug target/110598] [14 Regression] wrong code on llvm-14.0.6 due to memcmp being miscompiled

2023-07-12 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110598

--- Comment #5 from CVS Commits  ---
The master branch has been updated by Roger Sayle :

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

commit r14-2465-gd2c18b4a16f9e1a6ed271ec1efaf94533d1c4a94
Author: Roger Sayle 
Date:   Wed Jul 12 14:12:34 2023 +0100

PR target/110598: Fix rega = 0; rega ^= rega regression in i386.md

This patch fixes the regression PR target/110598 caused by my recent
addition of a peephole2.  The intention of that optimization was to
simplify zeroing a register, followed by an IOR, XOR or PLUS operation
on it into a move, or as described in the comment:
;; Peephole2 rega = 0; rega op= regb into rega = regb.

The issue is that I'd failed to consider the (rare and unusual) case,
where regb is rega, where the transformation leads to the incorrect
"rega = rega", when it should be "rega = 0".  The minimal fix is to
add a !reg_mentioned_p check to the recent peephole2.

In addition to resolving the regression, I've added a second peephole2
to optimize the problematic case above, which contains a false
dependency and is therefore tricky to optimize elsewhere.  This is an
improvement over GCC 13, for example, that generates the redundant:

xorl%edx, %edx
xorq%rdx, %rdx

2023-07-12  Roger Sayle  

gcc/ChangeLog
PR target/110598
* config/i386/i386.md (peephole2): Check !reg_mentioned_p when
optimizing rega = 0; rega op= regb for op in [XOR,IOR,PLUS].
(peephole2): Simplify rega = 0; rega op= rega cases.

gcc/testsuite/ChangeLog
PR target/110598
* gcc.target/i386/pr110598.c: New test case.

[Bug target/110598] [14 Regression] wrong code on llvm-14.0.6 due to memcmp being miscompiled

2023-07-12 Thread slyfox at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110598

--- Comment #6 from Sergei Trofimovich  ---
The change fixed test suite on llvm-14.0.6 and on llvm-12.0.1. Thank you!

[Bug target/110598] [14 Regression] wrong code on llvm-14.0.6 due to memcmp being miscompiled

2023-07-12 Thread roger at nextmovesoftware dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110598

Roger Sayle  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|ASSIGNED|RESOLVED
  Known to work||14.0

--- Comment #7 from Roger Sayle  ---
Many thanks to Sergei for confirming this issue is now resolved.  Sorry again
for the inconvenience.