Skip to content

SimplifyCFG removes needed path of computed goto #117724

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
FlameTop opened this issue Nov 26, 2024 · 9 comments
Closed

SimplifyCFG removes needed path of computed goto #117724

FlameTop opened this issue Nov 26, 2024 · 9 comments

Comments

@FlameTop
Copy link
Contributor

We have determined a case where required code in a computed goto flow is removed incorrectly. The included source has been cut-down from a more complex example and appears to be the simplest we can create to reproduce the fault. In the code the [0]th part of the computed goto is removed and replaced by the [2]nd path of the goto (can be determined by the the constant -0XDEADBEEF being absent from the assembly output).

It appears the commit
@

commit fc6bdb8
Author: XChy [email protected]
Date: Sat Oct 28 17:10:20 2023 +0800

[SimplifyCFG] Reland transform for redirecting phis between unmergeable BB and SuccBB (#68473)

Reland #67275 with #68953 resolved.

introduced this regression.

Small.CPP: '-S -O2' will reproduce.

#typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef short int int16_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned long long uint64_t;
using u8    = uint8_t;
using s16   = int16_t;
using u16   = uint16_t;
using s32   = int32_t;
using u32   = uint32_t;
union u128 {
  struct
  {
    uint32_t  w0, w1;
    uint32_t  w2, w3;
  };
  struct
  {
    uint64_t d0;
    uint64_t d1;
  };
};
namespace IDX{
enum _enum_t : u8
{
  x0 = 0,
  x1,    x2,
  x3,    x4,    x5,

  Invalid,
};
}


template< typename T >
union eState_t
{
  struct
  {
    T x0, x1, x2,
      x3, x4, x5;
  };
  T   m_r[IDX::Invalid];
};

using Pack128 = u128;
using eState128 = eState_t<Pack128>;
struct State
{
  eState128  sdta; 
};



void qaz(uint8_t *mem, State &__restrict data){
  uint32_t switchval = ~0;
  data.sdta.m_r[(IDX::x5)].d0 = data.sdta.m_r[(IDX::x3)].d0;
  switchval = data.sdta.m_r[(IDX::x2)].d0;
  static constexpr void *switchdispatch[] = {
    &&L10,
    &&L20,
    &&L30,
    &&L40,
  };
  goto *switchdispatch[switchval];
  return;

L10:
  data.sdta.m_r[(IDX::x3)].d0 = 0xDEADBEEF;
  goto L200;
L20:
  if (auto reason = (data.sdta.m_r[(IDX::x1)].d0) == (data.sdta.m_r[(IDX::x0)].d0); (data.sdta.m_r[(IDX::x1)].d0 = (0x005b << 16)), reason) { goto L100; };
  if (auto reason = (0 == 0); (data.sdta.m_r[(IDX::x3)].d0 = (int32_t((data.sdta.m_r[(IDX::x1)].w0) + 0x5d00))), reason) { goto L200; };
L30:
  data.sdta.m_r[(IDX::x1)].d0 = (0x005b << 16) ;
  if (auto reason = (0 == 0); (data.sdta.m_r[(IDX::x3)].d0 = (int32_t((data.sdta.m_r[(IDX::x1)].d0) + 0x5d40))), reason) { goto L200; };
L40:
  if(auto reason = ((data.sdta.m_r[(IDX::x1)].d0) != ( 0 )); reason) { (data.sdta.m_r[(IDX::x3)].d0 = (s32)((s32 &)mem[(u32)(((IDX::x5)) + (0x398))])); goto L200; };
L100:
  data.sdta.m_r[(IDX::x1)].d0 = (0x005b << 16);
  data.sdta.m_r[(IDX::x3)].d0 = data.sdta.m_r[(IDX::x1)].w0 + 0x5ce0;
L200:
  if(auto reason = ((data.sdta.m_r[(IDX::x3)].d0) == ( 0 )); data.sdta.m_r[(IDX::x1)].d0 = ((data.sdta.m_r[(IDX::x3)].d0) + 0), reason) { goto L300; };
  data.sdta.m_r[(IDX::x2)].d0 = (uint32_t)(uint32_t((u16)((s16 &)mem[(u32)(( data.sdta.m_r[(IDX::x3)].d0) + (0xa))])));
L300:
  return;

}
@FlameTop FlameTop changed the title SimplfyCFG removes needed path of computed goto SimplifyCFG removes needed path of computed goto Nov 26, 2024
@nikic
Copy link
Contributor

nikic commented Nov 26, 2024

Do you see this on current main? This looks like the issue 3c9022c fixed.

@FlameTop
Copy link
Contributor Author

I am still seeing the problem and have confirmed commit 3c9022c is present and correct in my build. I am also seeing the problem on Compiler Explorer trunk build

'''clang version 20.0.0git (https://github.com/llvm/llvm-project.git 4527894)'''

which appears to be up to date as of 26th November 2024, so do not think this is a local build problem.

@nikic
Copy link
Contributor

nikic commented Nov 27, 2024

Can you share the compiler explorer link? In https://clang.godbolt.org/z/z58j37661 I see the constant 3735928559.

@FlameTop
Copy link
Contributor Author

Argh, apologies I had the wrong explorer page open and was looking at the LLVM 19 results (in which it is broken). I can now see that compiler explorer trunk build does work ok. I need to dig and find why my local build of main still exhibits the problem.

@nikic
Copy link
Contributor

nikic commented Nov 27, 2024

There was a followup fix yesterday in 39601a6, so maybe your local build doesn't have that one?

@nikic
Copy link
Contributor

nikic commented Nov 27, 2024

For the record, #117869 is the backport PR.

@FlameTop
Copy link
Contributor Author

Ah, thank you I did not have yesterday's follow-up fix. Rebuilding now to confirm my local build works.

@FlameTop
Copy link
Contributor Author

I have confirmed the fix 39601a6 from yesterday does fix my local build.

Again apologies for wasting your time; just my luck to report a bug the day its fixed.

regards

Phil

@nikic
Copy link
Contributor

nikic commented Nov 28, 2024

Heh, no luck involved -- the original fix only got a second look because of this report :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants