This is an archive of the discontinued LLVM Phabricator instance.

[SROA] fix assetion failure
ClosedPublic

Authored by inouehrs on Jan 11 2018, 10:30 PM.

Details

Summary

This patch fixes the assertion failure in SROA reported in PR35657.
PR35657 reports the assertion failure due to r319522 (splitting for non-whole-alloca slices), but this problem can happen even without r319522.

The problem exists in a check for reusing an existing alloca when rewriting partitions. As the original comment said, we can reuse the existing alloca if the new alloca has the same type and offset with the existing one. But the code checks only type of the alloca and then check the offset using an assert.
In a corner case with out-of-bounds access (e.g. @PR35657 function added in unit test), it is possible that the two allocas have the same type but different offsets.

This patch makes the check of the offset in the if condition, and re-enables the splitting for non-whole-alloca slices.

Diff Detail

Repository
rL LLVM

Event Timeline

inouehrs created this revision.Jan 11 2018, 10:30 PM
rnk added inline comments.Jan 12 2018, 10:49 AM
lib/Transforms/Scalar/SROA.cpp
130 ↗(On Diff #129580)

Can you delete this flag instead and simplify the logic that checks it?

test/Transforms/SROA/basictest.ll
1712 ↗(On Diff #129580)

WOW, I guess this isn't UB because the storage size of i48 is 8 bytes, right? Crazy.

inouehrs updated this revision to Diff 129670.EditedJan 12 2018, 11:17 AM
  • eliminated SROASplitNonWholeAllocaSlices flag
inouehrs marked an inline comment as done.Jan 12 2018, 11:21 AM
efriedma added inline comments.Jan 12 2018, 2:01 PM
test/Transforms/SROA/basictest.ll
1712 ↗(On Diff #129580)

No, this is UB; an i48 has a storage size of 6 bytes.

Granted, we still shouldn't crash.

It looks like this doesn't properly fix PR35657; it fixes the crash, yes, but it looks like the optimizer is introducing undefined behavior.

inouehrs updated this revision to Diff 129752.Jan 13 2018, 1:19 AM

fixed an unit test to avoid emitting undef values.

It looks like this doesn't properly fix PR35657; it fixes the crash, yes, but it looks like the optimizer is introducing undefined behavior.

I updated the test case to avoid undef in the generated code due to loads from uninitialized alloca.
Do you expect other behavior (such as not applying SROA for out-of-bounds accesses)?

efriedma accepted this revision.Jan 15 2018, 4:20 PM

LGTM, but don't close PR35657 until you track down the miscompile. (csmith should not be generating code with out-of-bounds accesses, so there's probably another bug somewhere.)

lib/Transforms/Scalar/SROA.cpp
3933 ↗(On Diff #129752)

Please add a comment explaining that beginOffset() != 0 can happen for out-of-bounds accesses. (We want to transform anyway because we don't want undefined behavior in unreachable code to block optimizations in other code.)

This revision is now accepted and ready to land.Jan 15 2018, 4:20 PM
This revision was automatically updated to reflect the committed changes.