This is an archive of the discontinued LLVM Phabricator instance.

[LoopVectorize] Fix crash on "Cannot dereference end iterator!"(PR56627)
ClosedPublic

Authored by LiDongjin on Oct 18 2022, 9:35 PM.

Details

Summary

Before use hasOneUser it must Check hasOneUser.

Check hasOneUser before user_back()

https://github.com/llvm/llvm-project/issues/56627

test file:
https://godbolt.org/z/3YqEzs45z

Diff Detail

Event Timeline

LiDongjin created this revision.Oct 18 2022, 9:35 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 18 2022, 9:35 PM
LiDongjin requested review of this revision.Oct 18 2022, 9:35 PM
dmgreen accepted this revision.Oct 20 2022, 1:14 AM
dmgreen added a subscriber: dmgreen.

I see, dead instructions in the loop. You would hope those would have been simplified away.

Sounds OK as a fix. LGTM

This revision is now accepted and ready to land.Oct 20 2022, 1:14 AM
fhahn added inline comments.Oct 20 2022, 1:45 AM
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
6567

Could you instead use match(RetI, m_OneUse())?

llvm/test/Transforms/LoopVectorize/pr56627.ll
5 ↗(On Diff #468779)

Is this test over-reduced or missing some flags? It seems to not crash on current main: https://llvm.godbolt.org/z/5vn4Tj9xM

LiDongjin updated this revision to Diff 469459.Oct 20 2022, 8:33 PM
LiDongjin edited the summary of this revision. (Show Details)

Changes the hasOneUser() to m_OneUse(m_Value())

add the triple info for the test and move it into aarch64

dmgreen requested changes to this revision.Oct 21 2022, 6:15 AM
dmgreen added inline comments.
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
6560

This is very deliberately OneUser, not OneUse. It needs to match mul(zext(x), zext(x))

6567

Mul is probably OK with OneUse. Can it use if (match(RetI, m_OneUse(m_Mul(m_Value(), m_Value())))) {

llvm/test/Transforms/LoopVectorize/AArch64/pr56627.ll
2

I think you need to remove -force-vector-width=2 to reproduce the original issue.

This revision now requires changes to proceed.Oct 21 2022, 6:15 AM
LiDongjin added inline comments.Oct 23 2022, 1:57 AM
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
6560

Yes, That's my mistakes which I misunderstood the code here.

6567

Dose It seems likes:

if (match(RetI, m_OneUse(m_Mul(m_Value(), m_Value())))) {
  if (RetI->user_back()->getOpcode() == Instruction::Add)
    RetI = RetI->user_back();
}
if(match(RetI, m_Mul(m_Value(), m_Value())) && !match(RetI, m_OneUse(m_Value()))) {
  return None;
}
llvm/test/Transforms/LoopVectorize/AArch64/pr56627.ll
2

Yes, I have some confuse about this test.
For the original issue, It needs to produce the reduce instruction to trigger the crash bug. So it seems that we do not need to test every line in the final vectorize program which we just check program can run without crash.

And if i remove -force-vector-width=2, Is there some future changes that disables or changes the vectorize of this program ? (like enable vector-width=4 or not produce vectorize program)
So Can i just use the simple test like below:

; RUN: opt < %s -S -passes=loop-vectorize | FileCheck %s
; Check that we can vectorize this loop without crashing.

target triple = "aarch64-none-linux-gnu"
define void @quux() {
; CHECK-LABEL: @quux(

But it seems the test can not enough to trrigle bug that check we produce reduce instr

; CHECK: call float @llvm.vector.reduce.fadd.v2f32

So i think this check is necessary, and use -force-vector-width=2 to ensure correct with any changes

dmgreen added inline comments.Oct 24 2022, 4:25 AM
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
6560

It's quite subtle and doesn't have a test. I'll see about adding one.

6567

IIRC the Mul will not be matched in InLoopReductionImmediateChains, as we are (usually) trying to match add(mul(...)). So I think the second if would not be needed.

llvm/test/Transforms/LoopVectorize/AArch64/pr56627.ll
2

This example doesn't seem to trigger the crash: https://llvm.godbolt.org/z/czfz7qsoq
It does if the -force-vector-width=2 is removed: https://llvm.godbolt.org/z/cqMzTTvj1
So from that, the argument needs to be removed. Are you seeing something different?

I think that other than that, the test seems OK to me. The auto-generated check lines are OK to keep, and the comment explains that we are really protecting from a crash. The check lines could be reduced, but the auto-generated check lines are pretty standard-practice.

LiDongjin updated this revision to Diff 470463.Oct 25 2022, 6:35 AM
LiDongjin added inline comments.Oct 25 2022, 6:42 AM
llvm/test/Transforms/LoopVectorize/AArch64/pr56627.ll
2

I remove the -force-vector-width=2 to keep the testcase same with origin.
But the testcase will not vectorize,So i just check the func label for now.

dmgreen accepted this revision.Oct 25 2022, 1:33 PM

Thanks LGTM

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
6568

This can drop the brackets around RetI->user_back()->getOpcode() == Instruction::Add

llvm/test/Transforms/LoopVectorize/AArch64/pr56627.ll
2

That makes sense if the in-loop reduction is going to be expensive. If you wanted to run the update_test_checks script I wouldn't be against the check lines. It's a bit of extra testing, even if it isn't needed for this issue exactly. Up to you.

This revision is now accepted and ready to land.Oct 25 2022, 1:33 PM
LiDongjin updated this revision to Diff 470690.Oct 25 2022, 8:45 PM

delete brackets

fhahn accepted this revision.Oct 30 2022, 1:57 PM

LGTM with the additional comments, thanks!

llvm/test/Transforms/LoopVectorize/AArch64/pr56627.ll
4

Would be good to check if we are at least vectorizing (i.e. check at least for vector.body: )

18

this block can be folded in the previous one.

19

might be better to increment this by a value != 0.0

25

Better to return the value to make it used.

52

might be better to increment this by a value != 0.0

LiDongjin added inline comments.Nov 2 2022, 1:14 AM
llvm/test/Transforms/LoopVectorize/AArch64/pr56627.ll
4

the cost model seems not vectorize this problem code. And if i use '-force-vector=4',it will not triggle the crash problem.

18

Done

19

Done

25

Done

LiDongjin updated this revision to Diff 472530.Nov 2 2022, 1:26 AM
LiDongjin edited the summary of this revision. (Show Details)
LiDongjin removed a reviewer: greened.