This is an archive of the discontinued LLVM Phabricator instance.

[Transform] Rewrite LowerSwitch using APInt
ClosedPublic

Authored by Peter on Dec 28 2022, 5:49 PM.

Details

Summary

This rewrite fixes https://github.com/llvm/llvm-project/issues/59316.

Previously LowerSwitch uses int64_t, which will crash on case branches using integers with more than 64 bits.
Using APInt fixes this problem. This patch also includes a test

Diff Detail

Event Timeline

Peter created this revision.Dec 28 2022, 5:49 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 28 2022, 5:49 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
Peter requested review of this revision.Dec 28 2022, 5:49 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 28 2022, 5:49 PM
Peter retitled this revision from [Transform] Rewrite LowerSwitch using APInt This rewrite fixes https://github.com/llvm/llvm-project/issues/59316. Previously LowerSwitch uses int64_t, which will crash on case branches using integers with more than 64 bits. Using APInt fixes... to [Transform] Rewrite LowerSwitch using APInt.Dec 28 2022, 5:52 PM
Peter edited the summary of this revision. (Show Details)
Peter added reviewers: RKSimon, spatel, aeubanks, hans.
arsenm added a subscriber: arsenm.Dec 28 2022, 6:00 PM
arsenm added inline comments.
llvm/lib/Transforms/Utils/LowerSwitch.cpp
277

This was >= before

328–331

const ref?

436

APSint?

llvm/test/Transforms/LowerSwitch/pr59316.ll
1

Needs checks

3

Use opaque pointers

14

Don't use anonymous values

18

Does this test cover all the paths?

Peter updated this revision to Diff 485573.Dec 28 2022, 8:38 PM
Peter marked 2 inline comments as done.
  1. update tests
  2. use APSInt
  3. fix some other problems I forgot to fix.
Peter marked 5 inline comments as done.Dec 28 2022, 8:38 PM
Peter updated this revision to Diff 485574.Dec 28 2022, 8:41 PM

use const ref when possible

nikic added a subscriber: nikic.Dec 29 2022, 1:47 AM

Why do some parts of this use APSInt?

RKSimon added inline comments.Jan 1 2023, 4:13 AM
llvm/lib/Transforms/Utils/LowerSwitch.cpp
358

Please remove / pre-commit any clang-format only changes to untouched code

442

Do we not have a static helper to create values like this?

Peter updated this revision to Diff 485885.Jan 2 2023, 1:27 PM
  1. precommit format
  2. using APSInt static constructor for SignedMin and SignedMax
Peter marked 2 inline comments as done.Jan 2 2023, 1:27 PM

Why do some parts of this use APSInt?

The old code assumes the branch case to be signed integer (int64_t), therefore some place use APSInt to make signess more clear.

nikic requested changes to this revision.Jan 2 2023, 1:33 PM

Why do some parts of this use APSInt?

The old code assumes the branch case to be signed integer (int64_t), therefore some place use APSInt to make signess more clear.

APSInt is only used if you need to dynamically switch between signed and unsigned operations. Otherwise APInt with appropriate operations is used -- there are signed and unsigned variants for all operations where it makes a difference.

This revision now requires changes to proceed.Jan 2 2023, 1:33 PM
Peter updated this revision to Diff 485888.Jan 2 2023, 1:45 PM

use APInt instead of APSInt

a couple of minor style comments

llvm/lib/Transforms/Utils/LowerSwitch.cpp
462

(style) assert message

490–491

(style) Assert message

nikic resigned from this revision.Jan 4 2023, 2:04 AM
Peter updated this revision to Diff 486470.Jan 4 2023, 9:56 PM
Peter marked 2 inline comments as done.

add assert info

Peter added inline comments.Jan 4 2023, 10:04 PM
llvm/lib/Transforms/Utils/LowerSwitch.cpp
490–491

Done

RKSimon accepted this revision.Jan 5 2023, 9:42 AM

LGTM

This revision is now accepted and ready to land.Jan 5 2023, 9:42 AM
This revision was automatically updated to reflect the committed changes.

Hello,

The following starts crashing with this patch:

opt -passes=lowerswitch bbi-77637.ll -o /dev/null

It fails with

opt: ../lib/Transforms/Utils/LowerSwitch.cpp:461: void (anonymous namespace)::ProcessSwitchInst(llvm::SwitchInst *, SmallPtrSetImpl<llvm::BasicBlock *> &, llvm::AssumptionCache *, llvm::LazyValueInfo *): Assertion `N.sge(SignedZero) && "Popularity shouldn't be negative."' failed.

bjope added a subscriber: bjope.Jan 12 2023, 2:56 AM
RKSimon added inline comments.Jan 12 2023, 6:12 AM
llvm/lib/Transforms/Utils/LowerSwitch.cpp
462

It looks like this can't handle i1 types properly

Peter reopened this revision.Jan 12 2023, 10:41 AM

Not just i1 but for any type. (Easiest to trigger on i1 tho).

The root cause is N = High - Low + 1 may overflow to a negative number. (Imagine i32 N = i32::max - i32::min + 1 as signed.)
Promoting N and Pop to higher precision would help. I am working on it.

This revision is now accepted and ready to land.Jan 12 2023, 10:41 AM
Peter updated this revision to Diff 488718.Jan 12 2023, 11:01 AM

Popularity is now represented using higher precision unsigned APInt to avoid overflow

Peter updated this revision to Diff 488721.Jan 12 2023, 11:04 AM

add comments

Peter requested review of this revision.Jan 12 2023, 11:18 AM
arsenm added inline comments.Jan 12 2023, 11:30 AM
llvm/lib/Transforms/Utils/LowerSwitch.cpp
461

I don't understand why this wouldn't just be unsigned to begin with

Peter marked an inline comment as done.Jan 12 2023, 11:40 AM
Peter added inline comments.
llvm/lib/Transforms/Utils/LowerSwitch.cpp
461

Old version used int64_t N, which would have the same problem.

We see the

Assertion `N.sge(SignedZero) && "Popularity shouldn't be negative."' failed.

crash fairly often in downstream fuzz testing.
Is someone planning to push a fix?

Peter marked an inline comment as done.Jan 20 2023, 12:45 PM

We see the

Assertion `N.sge(SignedZero) && "Popularity shouldn't be negative."' failed.

crash fairly often in downstream fuzz testing.
Is someone planning to push a fix?

I think this problems have already been fixed in this patch. I am waiting for someone to review it before I patch it.

Peter marked an inline comment as done.Jan 20 2023, 12:46 PM
arsenm added inline comments.Jan 20 2023, 2:27 PM
llvm/lib/Transforms/Utils/LowerSwitch.cpp
461

Right, so why isn’t it OK to just switch to always using unsigned?

Peter marked an inline comment as done.Jan 20 2023, 2:42 PM
Peter added inline comments.
llvm/lib/Transforms/Utils/LowerSwitch.cpp
461

Well, old version has existed and works for years, I figure we shouldn't change that decision unless we have a good reason

And I now this (fixed) bug gave us a reason. :)

Peter marked an inline comment as done.Jan 20 2023, 2:44 PM
RKSimon accepted this revision.Jan 24 2023, 5:23 AM

LGTM

This revision is now accepted and ready to land.Jan 24 2023, 5:23 AM
This revision was automatically updated to reflect the committed changes.