This is an archive of the discontinued LLVM Phabricator instance.

[MemoryBuiltins] Add field for alignment argument
ClosedPublic

Authored by Bryce-MW on Jan 7 2022, 9:35 PM.

Details

Summary

There are a few places where the alignment argument for AlignedAllocLike functions was previously hardcoded. This goes along with removing hardcoded arguments for the allocation size. It also allows alligned operator new to be given an alignment value in InstCombinerImpl::annotateAnyAllocSite and makes Heap To Stack add the proper alignment for aligned new. I'm sure this isn't the best way to do this but I am new to the LLVM codebase so I appreciate any suggestions on how to improve.

Diff Detail

Event Timeline

Bryce-MW created this revision.Jan 7 2022, 9:35 PM
Bryce-MW requested review of this revision.Jan 7 2022, 9:35 PM
Herald added a reviewer: sstefan1. · View Herald Transcript
Herald added a reviewer: baziotis. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
Bryce-MW updated this revision to Diff 398313.Jan 7 2022, 10:41 PM
  • Fix build issue

The AllocationFnData table was not properly formatted before my modifications. When running clang-format, it changed the formatting of the entire table. I formatted it back to how it looked before but fixed a few issues with it. I think this looks better and is easier to read but I am happy to set it back to the way clang-format likes it if that is desired. Let me know. I think that was the only issue with the build.

xbolva00 added inline comments.
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
2594

Works fine currently but we should replace Call.getOperand(1) with some more general API like

getAllocSizeArg or so.

reames added a subscriber: reames.Jan 8 2022, 9:15 AM
reames added inline comments.
llvm/include/llvm/Analysis/MemoryBuiltins.h
75

Move this down to the new property section please.

76

I'd suggest changing the return value from the operand index to the Value * of the operand or nullptr. This seems like it would cleanup the current client code a bit, and would also allow us to return constant exprs for any allocation function whose alignment is a (known) function of the constant allocated size. I'm not suggesting you do the last bit, just that you leave the potential open.

llvm/lib/Transforms/IPO/AttributorAttributes.cpp
5957

I think this block would be cleaner as:
if (isAllocationfn(*AI.CB)) {

Value *Align = getAlignment(*AI.CB)
..

}

This lets you drop all the passing around indices.

6268–6270

Same.

Bryce-MW updated this revision to Diff 398361.Jan 8 2022, 12:28 PM
  • Return a Value and add a size call
Bryce-MW updated this revision to Diff 398362.Jan 8 2022, 12:34 PM
Bryce-MW marked 3 inline comments as done.
  • Remove the last index-based check
Bryce-MW marked 2 inline comments as done.Jan 8 2022, 12:40 PM

Thanks for the suggestions! I had a feeling that there would be a better way than passing indexes around. I think I've mostly implemented them correctly. I'm not entirely sure if my use of getInitialValueOfAllocation is correct. I am also not sure about the part where getAllocSize has the possibility of creating a multiplication. Maybe that should return a pair of Values and let the caller create a multiplication if it wants?

reames added a comment.Jan 8 2022, 1:03 PM

Please move the getAllocSize parts to it's own patch. We were converging on an LGTM for the alignment bits, and I want to keep the discussion focused on that.

reames requested changes to this revision.Jan 8 2022, 1:06 PM

I'd suggest leaving the Attributor change to it's own review. I'm not familiar enough to review it easily. Let's get the allocation accessor in, and then iterate.

llvm/lib/Analysis/MemoryBuiltins.cpp
278

Er, this does not work. You need to check that AlignmentParam is not -1, or this will crash.

This revision now requires changes to proceed.Jan 8 2022, 1:06 PM
Bryce-MW updated this revision to Diff 398394.Jan 8 2022, 10:39 PM
  • Rollback changes to Attributor and addition of size call
Bryce-MW marked an inline comment as done.Jan 8 2022, 10:45 PM

I've rolled back the addition of the size function and the changes to attributor that go with it (I'll put those together in a separate patch once this one is done). I've kept the changes to attributor that are related to alignment but I can remove those as well if you would like, I wasn't entirely sure if you meant for me to do that or not. Thanks!

llvm/lib/Analysis/MemoryBuiltins.cpp
278

Good point, for some reason I assumed getOperand would return null for that case. Do I also need to check if it's too large?

Bryce-MW updated this revision to Diff 398395.Jan 8 2022, 10:51 PM
Bryce-MW marked an inline comment as done.
  • Format (other than the table as mentioned)
reames added a comment.Jan 9 2022, 2:25 PM

LGTM for everything outside of Attributor - those lines I'm unsure of whether there's a missing precondition on the argument being constant.

Do you have commit access? If not, I can land the LGTMed parts for you.

I am assuming that I don't have commit access since this is my first contribution so I would appreciate you landing the changes outside of Attributor.

I agree that someone experienced with Attributor should look at it to be sure. Looking at it again, I think that it probably does assume that it is constant and while I could put in a check, I'm not sure if there is a way to back out if it was not (maybe this was an issue even with the original aligned_alloc?). getAssumedConstant will return nullptr if it is sure that the value is not constant. getAPInt will return none if the result from getAssumedConstant is neither a known constant nor none (unsure if constant or not). The like after the line I changed then asserts that the result from getAPInt has a value.

reames added a comment.Jan 9 2022, 5:07 PM

I am assuming that I don't have commit access since this is my first contribution so I would appreciate you landing the changes outside of Attributor.

Will do tomorrow morning.

So we're clear on the legal stuff, can you confirm that this is intended as a contribution to the LLVM project and that you agree to the license terms thereof?

I confirm that this is intended as a contribution to the LLVM project and that I agree to the license terms thereof.

reames accepted this revision.Jan 10 2022, 9:21 AM
This revision is now accepted and ready to land.Jan 10 2022, 9:21 AM
reames closed this revision.Jan 10 2022, 9:23 AM

Landed. When I went to land it, I noticed a couple of small issues, so this ended up being a small mini series rather than one patch.

commit 7febd60a90960ff1c74027c05394e134dad655a1 (HEAD -> main, origin/main)
Author: Bryce Wilson <bryce@brycemw.ca>
Date: Mon Jan 10 09:08:55 2022 -0800

[instcombine] Add align return attributes for operator new(..., align_val)

commit fb936595faa44ad9c8d8550b05ea95e7be5f4703
Author: Bryce Wilson <bryce@brycemw.ca>
Date: Mon Jan 10 08:58:44 2022 -0800

[MemoryBuiltins] Add field for alignment argument [NFC]

commit 332642e693509947d33ec5dbcbdc3fcf149f4a87
Author: Philip Reames <listmail@philipreames.com>
Date: Mon Jan 10 08:38:40 2022 -0800

Add test coverage for D116851

commit f4c54683d684100fffd307ddf773078429b83442
Author: Philip Reames <listmail@philipreames.com>
Date: Mon Jan 10 08:25:20 2022 -0800

[instcombine] Infer alignment for aligned_alloc with potentially zero size

BTW, https://clang.llvm.org/docs/AttributeReference.html#id330 ... is it broken just for me or.. ?

void *b(void *v, int align) __attribute__((alloc_size(2), alloc_align(2))) ;

void *b(void *v, int align) {
    return v;
}
; ModuleID = '/app/example.cpp'
source_filename = "/app/example.cpp"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn allocsize(1)
define dso_local i8* @_Z1bPvi(i8* readnone returned %0, i32 %1) local_unnamed_addr #0 {
  ret i8* %0
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn allocsize(1) "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"uwtable", i32 1}
!2 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git d23fa4f2f1319039b7d939a4bf68c493ba26b07a)"}

Clang seems to ignore alloc_align attribute?

BTW, https://clang.llvm.org/docs/AttributeReference.html#id330 ... is it broken just for me or.. ?
...
Clang seems to ignore alloc_align attribute?

If by "broken", you mean "unimplemented" yes. LLVM has no allocalign attribute.

(For the record, that's related, but not directly relevant to this patch. Your comment made it seem like there might be a regression here. I believe that not to be the case, do you agree?)

BTW, https://clang.llvm.org/docs/AttributeReference.html#id330 ... is it broken just for me or.. ?
...
Clang seems to ignore alloc_align attribute?

If by "broken", you mean "unimplemented" yes. LLVM has no allocalign attribute.

(For the record, that's related, but not directly relevant to this patch. Your comment made it seem like there might be a regression here. I believe that not to be the case, do you agree?)

Yes, not related to this patch, I was just curious about that (if you know something more about that, etc..). Thanks.

There probably should be an allocalign attribute in the future once allocation functions are less hardcoded

xbolva00 added inline comments.Jan 22 2022, 6:30 AM
llvm/lib/Analysis/MemoryBuiltins.cpp
64

Thinking about this again..

Maybe this should go to Clang?

We should really use allocsize attribute and annotate LibFuncs instead of using this hardcoded list.