This is an archive of the discontinued LLVM Phabricator instance.

clang: emit allocalign to LLVM for alloc_align attributes
Needs ReviewPublic

Authored by durin42 on Feb 8 2022, 11:58 AM.

Details

Summary

LLVM is growing knowledge of this, so we should inform it when we have
the information available. As a bonus, since we now check return
alignments in the callee as of an earlier patch of mine, we can now drop
the redundant llvm.assume() that this previously emitted.

Diff Detail

Event Timeline

durin42 created this revision.Feb 8 2022, 11:58 AM
durin42 requested review of this revision.Feb 8 2022, 11:58 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 8 2022, 11:58 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
xbolva00 added inline comments.
clang/test/CodeGen/alloc-align-attr.c
11–12

now this llvm.assume is redudant and should be removed?

durin42 added inline comments.Feb 10 2022, 9:21 AM
clang/test/CodeGen/alloc-align-attr.c
11–12

I don't think so? Right now allocalign doesn't mean a whole lot (it really just answers some questions that used to be inferred from function name by MemoryBuiltins.cpp) so I'd rather leave the llvm.assume given that I doubt it's hurting anyone?

jyknight added inline comments.Feb 10 2022, 6:44 PM
clang/lib/CodeGen/CGCall.cpp
4880

We do need to fallback to an assume for "if(CGF.SanOpts.has(SanitizerKind::Alignment)" however -- and NOT emit an allocalign (nor an align) attribute in that case.

This is necessary so that clang can emit explicit misalignment checks FIRST (and abort with a message if they fail), before letting LLVM assume the specified alignment. In order for the ubsan alignment check to work properly, we need to not trigger misalignment-UB before the check executes!

See clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function.cpp -- note how in the sanitized mode, it doesn't have an the "align 128" on the call result, but instead emits a bunch of code to test alignment, and branch to an ubsan abort on failure -- followed by the llvm.assume only on the successful branch. Although the test-case is only testing assume_aligned, the same behavior should be applicable to allocalign.

(Which shows that we clearly need a sanitized allocalign test-case, too)

clang/test/CodeGen/alloc-align-attr.c
11–12

I think we should get rid of the assume -- it's redundant. If we're emitting an allocalign attribute, I think we shouldn't bother emitting an align attribute, nor an assume.

The prior code either adds an "align" to the return value, or an assume instruction afterwards. Both of those are redundant with allocalign: the former will already be done automatically on the llvm side when the LLVM side sees a constant argument for an allocalign parameter, and the latter doesn't provide any more information than the allocalign itself does.

durin42 added inline comments.Feb 11 2022, 12:50 PM
clang/lib/CodeGen/CGCall.cpp
4880

It sounds like (between this comment and the one below) I should just abandon the code-sharing between AllocAlignAttrEmitter and AssumeAlignedAttrEmitter - is that right?

Also, should I be making a new test case or adding to an existing one for a sanitized allocalign test case? Is that an llvm-level thing or a clang-level thing?

durin42 updated this revision to Diff 408019.Feb 11 2022, 1:13 PM
durin42 edited the summary of this revision. (Show Details)
durin42 updated this revision to Diff 408097.Feb 11 2022, 4:15 PM
durin42 updated this revision to Diff 408116.Feb 11 2022, 5:07 PM
durin42 updated this revision to Diff 410058.Feb 18 2022, 7:34 PM
durin42 updated this revision to Diff 410558.Feb 22 2022, 9:02 AM
jyknight added inline comments.Feb 23 2022, 6:35 AM
clang/lib/CodeGen/CGCall.cpp
4880

Agree, it does sound like there's not going to be much code-sharing, since emitAlignmentAssumption is already separate. If you find it's clearer to make them be separate, that sounds reasonable.

Yes, there should be a test-case for sanitized allocalign, just like for sanitized assume_align.
This sanitizer is all in the frontend, see clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function.cpp

durin42 updated this revision to Diff 410896.Feb 23 2022, 11:58 AM
durin42 updated this revision to Diff 415230.Mar 14 2022, 2:25 PM
durin42 retitled this revision from CGCall: also emit LLVM `allocalign` attribute when handling AllocAlign to clang: emit allocalign to LLVM for alloc_align attributes.
durin42 edited the summary of this revision. (Show Details)
Herald added a project: Restricted Project. · View Herald TranscriptMar 14 2022, 2:25 PM
lebedev.ri added a subscriber: lebedev.ri.
lebedev.ri added inline comments.
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
97–98

This is a regression, the old behavior was correct.

durin42 added inline comments.Mar 14 2022, 2:55 PM
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
97–98

I don't think so: we now (as of D121629) check the alignment of the returned pointer in the callee instead of the caller, and LLVM knows about allocalign implying an alignment at the callsite. So I think it's correctly optimizing away the sanitizer checks here.

You or @jyknight will need to correct me if my understanding is incorrect here, but my understanding was that this change was what motivated D121629 in the first place.

lebedev.ri added inline comments.Mar 14 2022, 3:04 PM
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
97–98

I'm saying that as the author of said test and it's behavior.

durin42 added inline comments.Mar 14 2022, 3:08 PM
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
97–98

How is this wrong though? Are you concerned because the allocalign isn't being asserted upon by the sanitizer in the caller? How this a problem given that the callee code now does the assertions in sanitizer mode?

(If I'm not understanding please elaborate: this is my first nontrivial work on LLVM, so I'm going to need more than "I wrote this, and you are wrong" by way of help understanding my error.)

lebedev.ri added inline comments.Mar 14 2022, 3:13 PM
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
97–98

The original code was not relying on the happenstance that the called code would have been
compiled with sanitizers, and this new code does make such an assumption. This is a regression.
As i have said, we simply should not be emitting allocalign in such situation,
that would defeat the sanitizer check that should be emitted here.

jyknight added inline comments.Mar 14 2022, 3:23 PM
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
97–98

I suggested this change, which I think reasonable given that it's the same thing we are doing for null sanitization.

E.g. clang -fsanitize=null -emit-llvm -O2 -o - -S /tmp/test.cc on:

int &foo(int *x);

int bar(int*x) {
  return foo(x);
}

->

define dso_local noundef i32 @_Z3barPi(i32* noundef %x) local_unnamed_addr #0 {
entry:
  %call = tail call noundef nonnull align 4 dereferenceable(4) i32* @_Z3fooPi(i32* noundef %x)
  %0 = load i32, i32* %call, align 4, !tbaa !3
  ret i32 %0
}

There, too, we validate it in the callee before returning.

lebedev.ri added inline comments.Mar 14 2022, 3:29 PM
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
97–98

That may be your view on the situation, but i'm not sure i agree with it.
I think that is simply a bug. More concretely, now you will have a discrepancy with
e.g. catch-alignment-assumption-attribute-assume_aligned-on-function.cpp

durin42 planned changes to this revision.Apr 5 2022, 7:46 AM

I have some reworking to do on this after my latest round of llvm-side work that I'll try and get out later this week.

lebedev.ri resigned from this revision.Jan 12 2023, 4:58 PM

This review may be stuck/dead, consider abandoning if no longer relevant.
Removing myself as reviewer in attempt to clean dashboard.

durin42 requested review of this revision.Jun 7 2023, 3:05 PM
durin42 updated this revision to Diff 529447.
durin42 updated this revision to Diff 529616.Jun 8 2023, 8:49 AM

FYI: this is ready for review.