Skip to content

Wrong jump destination with -O2 -fexperimental-new-pass-manager #45203

@llvmbot

Description

@llvmbot
Bugzilla Link 45858
Resolution FIXED
Resolved on May 28, 2020 16:59
Version trunk
OS Windows NT
Blocks #44654
Reporter LLVM Bugzilla Contributor
CC @aeubanks,@zygoloid,@rnk,@tstellar,@hjyamauchi
Fixed by commit(s) fc93780 a634a80

Extended Description

Here's a reduced PoC on Compiler Explorer with clang (trunk):
https://gcc.godbolt.org/z/ZKn7Uq.
(This is a reduced version of Chromium's file //sandbox/win/src/filesystem_interception.cc.)

You can see the problem in the middle column. The right column (with -Os) demonstrates an expected behavior.

The problem happens at the if statement at the line 132888.
(In Chromium, it's https://source.chromium.org/chromium/chromium/src/+/master:sandbox/win/src/crosscall_params.h;l=251;drc=c8cff7f9663ce6d1ef35e5c717f43c867c3906eb.)

if ((size > sizeof(*this)) ||
    (param_info_[index].offset_ > (sizeof(*this) - size))) {
  // It does not fit, abort copy.
  return false;
}

In both the repro and the expected behavior, the second condition is compiled into "cmp rdx, rcx; jae", where rdx = (sizeof(*this) - size) and rcx = param_info_[index].offset_. So the destination of the JAE must be the code after the if statement.

In the repro case, however, the destination is .LBB2_9, which is the code inside the if block. I think the label .LBB2_9 must be placed at the "%bb.8".

This is not breaking Chromium because it's compiled with -Os, and -fexperimental-new-pass-manage is not set. I hit this when working on Firefox, which imports some of Chromium code, and Mozilla recently enabled -fexperimental-new-pass-manager.

Metadata

Metadata

Assignees

Labels

bugzillaIssues migrated from bugzillaclangClang issues not falling into any other category

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions