This is an archive of the discontinued LLVM Phabricator instance.

[SimplifyCFG] Don't SimplifyBranchOnICmpChain with ExtraCase
ClosedPublic

Authored by vitalybuka on Sep 4 2019, 6:19 PM.

Details

Summary

Here we try to avoid issues with "explicit branch" with SimplifyBranchOnICmpChain
which can check on undef. Msan by design reports branches on uninitialized
memory and undefs, so we have false report here.

In general msan does not like when we convert

// If at least one of them is true we can MSAN is ok if another is undefs
if (a || b)
  return;

into

// If 'a' is undef MSAN will complain even if 'b' is true
if (a)
  return;
if (b)
  return;

Example

Before optimization we had something like this:

while (true) {
  bool maybe_undef = doStuff();

  while (true) {
    char c = getChar();
    if (c != 10 && c != 13)
     continue
    break;
  }

  // we know that c == 10 || c == 13 if we get here,
  // so msan know that branch is not affected by maybe_undef
  if (maybe_undef || c == 10 || c == 13) 
    continue;
  return;
}

SimplifyBranchOnICmpChain will convert that into

while (true) {
  bool maybe_undef = doStuff();

  while (true) {
    char c = getChar();
    if (c != 10 && c != 13)
      continue;
    break;
  }

  // however msan will complain here:
  if (maybe_undef)
    continue; 

  // we know that c == 10 || c == 13, so either way we will get continue
  switch(c) {
    case 10: continue;
    case 13: continue;
  }
  return;
}

Event Timeline

vitalybuka created this revision.Sep 4 2019, 6:19 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 4 2019, 6:19 PM
vitalybuka updated this revision to Diff 218827.Sep 4 2019, 6:58 PM

Assertions really have been autogenerated by utils/update_test_checks.py

vitalybuka updated this revision to Diff 218828.Sep 4 2019, 7:02 PM

regenerate assertions with patched compiler

vitalybuka edited the summary of this revision. (Show Details)Sep 5 2019, 10:55 AM
vitalybuka edited the summary of this revision. (Show Details)Sep 5 2019, 11:07 AM
vitalybuka edited the summary of this revision. (Show Details)Sep 5 2019, 11:16 AM
vitalybuka edited the summary of this revision. (Show Details)
vitalybuka edited the summary of this revision. (Show Details)Sep 5 2019, 11:18 AM

You description of the issue uses "||" in the pseudo-code; I assume you actually mean a non-short-circuiting "|"?

Is there a general description somewhere of what restrictions msan places on IR transforms vs. normal IR semantics? It's not obvious to me that this transform, specifically, is incorrect, as opposed to whatever transform is producing this IR.

llvm/lib/Transforms/Utils/SimplifyCFG.cpp
3748

Can you fix this so we return early before the LLVM_DEBUG log?

vitalybuka updated this revision to Diff 218971.Sep 5 2019, 1:12 PM
vitalybuka marked 2 inline comments as done.

early return

Basically, the only rule is that you should not speculatively introduce a conditional branch on value that might be undef and is not guaranteed to execute in the input IR.

You can find an investigation of a similar problem in LoopUnswitch in this bug:
https://bugs.llvm.org/show_bug.cgi?id=28054
It has some ideas of a better approach at the end, but we never acted on those. It sounds like a very hard problem.

You description of the issue uses "||" in the pseudo-code; I assume you actually mean a non-short-circuiting "|"?

yes, updated description

Is there a general description somewhere of what restrictions msan places on IR transforms vs. normal IR semantics? It's not obvious to me that this transform, specifically, is incorrect, as opposed to whatever transform is producing this IR.

I don't have one. @eugenis ?

efriedma accepted this revision.Sep 5 2019, 1:29 PM

LGTM

Basically, the only rule is that you should not speculatively introduce a conditional branch on value that might be undef and is not guaranteed to execute in the input IR.

That makes sense... can we put a brief description of that in LangRef?

This revision is now accepted and ready to land.Sep 5 2019, 1:29 PM
eugenis accepted this revision.Sep 5 2019, 3:46 PM

LGTM

I'll update LangRef.

This revision was automatically updated to reflect the committed changes.