This is an archive of the discontinued LLVM Phabricator instance.

Fix SROA creating invalid bitcasts between address spaces
ClosedPublic

Authored by arsenm on Sep 26 2013, 12:46 PM.

Details

Reviewers
chandlerc

Diff Detail

Event Timeline

david.tweed added inline comments.Nov 21 2013, 4:05 AM
lib/Transforms/Scalar/SROA.cpp
2530

The patch as a whole seems to make sense, but I wonder if it might make sense in the long run to add a convenience member function "getPointerToInSameAddrSpace(OtherPtr)"? It probably depends how many places crop up that need this, but if more are going to turn up it might be clearer. Not sure.

This patch fixes http://llvm.org/bugs/show_bug.cgi?id=15907 for me. It applies to LLVM 3.4 and make check passes. Could we get this in there also?

I think it's important to stop the crashing when doing SROA on this kind of code. This patch seems like the right way to do this, so I think moving it in to trunk (at least) is warranted. However, I don't claim to fully understand the intricacies of SROA so I'd prefer someone knowledgeable to do another pass on this.

joey added inline comments.Dec 3 2013, 7:17 AM
lib/Transforms/Scalar/SROA.cpp
1432

This line can also crash! I'll try get a test case.

joey added inline comments.Dec 5 2013, 10:14 AM
lib/Transforms/Scalar/SROA.cpp
1432

Here is the test case, it runs with 'opt -sroa'.

target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32-S64"
target triple = "armv7-none-linux-gnueabi"

%struct.struct_test_27.0.13 = type { i32, float, i64, i8, [4 x i32] }

; Function Attrs: nounwind
define void @copy_struct([5 x i64] %in.coerce) {
for.end:
  %in = alloca %struct.struct_test_27.0.13, align 8
  %0 = bitcast %struct.struct_test_27.0.13* %in to [5 x i64]*
  store [5 x i64] %in.coerce, [5 x i64]* %0, align 8
  %scevgep9 = getelementptr %struct.struct_test_27.0.13* %in, i32 0, i32 4, i32 0
  %scevgep910 = bitcast i32* %scevgep9 to i8*
  call void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)* undef, i8* %scevgep910, i32 16, i32 4, i1 false)
  ret void 
}

; Function Attrs: nounwind 
declare void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)* nocapture, i8* nocapture readonly, i32, i32, i1)
arsenm updated this revision to Unknown Object (????).Dec 6 2013, 12:30 PM

Merge in other SROA address patches I had lying around, add another testcase.

Ping

lib/Transforms/Scalar/SROA.cpp
1432

This works for me. I have a couple more patches that fix SROA address spaces that I missed on the first pass, but they don't seem necessary to also fix this.

Matt, this change is simply not in a useful state to review, much less commit.

To try to give you an idea of how broken this currently is, I spent the afternoon working through it.

  1. The change as posted doesn't pass its own tests. It appears you merged the test changes from D1765 into here, but not the code changes? I backed those out to get to a state that passed its own tests.
  2. Several of the changes which seem correct don't actually get exercised by any of your tests. It's not surprising as these changes are used to form GEPs and other complex pointers, and none of your test cases do anything like this. The only thing you have tested is doing memcpy across address spaces. So only those changes really make sense.
  3. One of the changes to the memcpy rewriting also didn't get exercised by your existing test cases. This is because that change is to the "vector-load" based memcpy rewriting rules and none of your test cases trigger vector rewriting.
  4. Right above the changes you made to memcpy rewriting is a totally separate (and important!) path for memcpy rewriting where we form a *new* memcpy. You didn't write any test cases for this. In fact, doing so would also provide a the root of a test case for the change Joey found (I don't know off hand what all would be required).
  5. Several of your changes are to code for rewriting loads and stores. The only loads and stores SROA currently rewrites are *alloca* loads and stores, so these changes are actually unnecessary given the current semantic constraint model which SROA operates under: alloca pointers are always in the default address space.
  6. Despite the changes I mention in #5, you didn't fix any of the *other* numerous places where we create loads, stores, or pointer casts in SROA for alloca-derived pointers, and so even if we were to allow allocas in different address spaces, the change as it stands doesn't seem like a principled change in that direction (although it might be a good incremental step).

I now have a minimal patch and 3 test cases which fix half of memcpy rewriting. If you can provide a test case for vector-load/store based memcpy rewriting which exercises the 3'rd aspect of that change, I would be happy to submit that as a first step. That is what I would pursue as the next step to make forward progress.

After that, you should provide test cases which exercise the other half of memcpy rewriting at all, and fixes the obvious bugs there.

Finally you should provide test cases which form interesting pointer adjustments including complex "natural" GEPs in the process of memcpy rewriting in order to flush out the bugs inside of getAdjustedPtr (and getNaturalGEPWithOffset). This will probably also require the first change in D1765 (I think, this I haven't actually tested as I was trying to get through D1764).

I have left comments in-line on the patch to highlight which changes are which, and to provide clarification.

-Chandler

lib/Transforms/Scalar/SROA.cpp
1327

No test case actually requires this change. I think this is actually necessary, but we really need a test case for it.

1428–1430

I also think this change is likely necessary, but again no test case fails if I delete it. We need a test case here as well.

1432

Joey, I have run this test case through opt with just the two diff hunks that are were already tested, and it passed for me every time I tried it.

2118

This change is unnecessary.

2143

This change is unnecessary.

2254–2256

This change is unnecessary.

2546

Undoing this change doesn't cause any test regressions. This change is *definitely* correct, but still needs a test case.

Thanks for the review! Some of the pieces aren't supposed to be strictly necessary. I'm also trying to get rid of the default address space arguments, and it seems like a better idea to do the consistent thing and get the address space from the value rather than hardcoding to 0 since you know it's an alloca derived pointer. I'll work on updating the tests tomorrow

arsenm updated this revision to Unknown Object (????).Dec 12 2013, 1:55 PM

Add / replace some tests to hit a few more lines, resplit removing default address space arguments to separate patch

FWIW, I just tested that the updated patch still fixes the issue I saw and applies to the 3.4 branch.

Hi,

Is this being progressed? I've encountered this issue recently on trunk (r199497) so the problem is still there.
It would be really nice to have a fix for this go into trunk.

Thanks,
Silviu

rafael added inline comments.Feb 13 2014, 4:44 PM
test/Transforms/SROA/basictest.ll
4

Why do you need to change this? Nothing on this test uses an address space.

arsenm added inline comments.Feb 13 2014, 5:04 PM
test/Transforms/SROA/basictest.ll
4

This belongs with the one of my other SROA patches which does touch this test

arsenm added inline comments.Feb 13 2014, 5:10 PM
test/Transforms/SROA/basictest.ll
4

Actually, it's used in this one too with the newly added @PR14105_as1 test


Matt Arsenault wrote:

Rafael Ávila de Espíndola wrote:

Why do you need to change this? Nothing on this test uses an address space.

This belongs with the one of my other SROA patches which does touch this test

Actually, it's used in this one too with the newly added @PR14105_as1 test

Sorry. In phab it looked like a new file when I first looked at it.

Cheers,
Rafael

Sorry. In phab it looked like a new file when I first looked at it.

OK, I tried to take a quick look, but there is no way that I can get
enough confidence on how SROA works in a short time.

In the end I just extracted a trivial cleanup from this patch
(r201425) and rebased it on trunk (attached).

I also checked that every use of an address space in the patch is tested.

Cheers,
Rafael

  • {F37588, layout=link}
chandlerc accepted this revision.Feb 26 2014, 12:33 AM

After fighting some fires in SROA, all of the state for this was fresh in my head so I took another look at this.

The patch looked essentially good at this point (and thanks for helping with the test case validation Rafael!), but pointed out some really terrible factoring and cleanup in the memcpy rewriter. I've cleaned all of that cruft up, and applied a rebased version of this patch with just a few tweaks in r202247.

arsenm closed this revision.Feb 26 2014, 11:48 AM

Can we get this into the 3.4.1 branch?