Page MenuHomePhabricator

Fix __builtin_assume_aligned with too large values.
ClosedPublic

Authored by erichkeane on Oct 10 2019, 12:22 PM.

Details

Summary

Code to handle __builtin_assume_aligned was allowing larger values, but
would convert this to unsigned along the way. This patch removes the
EmitAssumeAligned overloads that take unsigned to do away with this
problem.

Additionally, it adds a warning that values greater than 1 <<29 are
ignored by LLVM.

Diff Detail

Event Timeline

erichkeane created this revision.Oct 10 2019, 12:22 PM

Thanks, i like it.

clang/lib/CodeGen/CodeGenFunction.cpp
2058–2060

Just remove.

clang/lib/CodeGen/CodeGenFunction.h
2831–2832

Just remove.

clang/lib/Sema/SemaChecking.cpp
6066

(1ULL << 29ULL).
Is there some define for this somwhere, don't like magic numbers.

Remove unused code

hfinkel added inline comments.Oct 10 2019, 12:45 PM
clang/include/clang/Basic/DiagnosticSemaKinds.td
2854

Should this be in the IgnoredAttributes group? The builtin is not an attribute.

Also, I'd rather that the wording were similar to that used by err_attribute_aligned_too_great and other errors, and use 268435456 (which is what we get for MaxValidAlignment based on LLVM restrictions) instead of '1 << 29'.

clang/lib/Sema/SemaChecking.cpp
6066

Yep, there's Value::MaximumAlignment.

We have:

// Alignment calculations can wrap around if it's greater than 2**28.
unsigned MaxValidAlignment =
    Context.getTargetInfo().getTriple().isOSBinFormatCOFF() ? 8192
                                                            : 268435456;

in Sema::AddAlignedAttr. which also has the magic-number problem.

erichkeane marked 5 inline comments as done.

Hal's comments

lebedev.ri accepted this revision.Oct 10 2019, 1:05 PM

LG, thanks.

This revision is now accepted and ready to land.Oct 10 2019, 1:05 PM

cant use llvm::Value in Sema without some linker issues.

thakis added a subscriber: thakis.Oct 10 2019, 2:26 PM

The new test fails on Windows:

-- Testing: 16032 tests, 32 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50
FAIL: Clang :: Sema/builtin-assume-aligned.c (8862 of 16032)
******************** TEST 'Clang :: Sema/builtin-assume-aligned.c' FAILED ********************
Script:
--
: 'RUN: at line 1';   c:\src\llvm-project\out\gn\bin\clang.exe -cc1 -internal-isystem c:\src\llvm-project\out\gn\lib\clang\10.0.0\include -nostdsysteminc -fsyntax-only -verify C:\src\llvm-project\clang\test\Sema\builtin-assume-aligned.c
--
Exit Code: 1

Command Output (stdout):
--
$ ":" "RUN: at line 1"
$ "c:\src\llvm-project\out\gn\bin\clang.exe" "-cc1" "-internal-isystem" "c:\src\llvm-project\out\gn\lib\clang\10.0.0\include" "-nostdsysteminc" "-fsyntax-only" "-verify" "C:\src\llvm-project\clang\test\Sema\builtin-assume-aligned.c"
# command stderr:
error: 'warning' diagnostics expected but not seen: 
  File C:\src\llvm-project\clang\test\Sema\builtin-assume-aligned.c Line 62: requested alignment must be 268435456 bytes or smaller; assumption ignored
error: 'warning' diagnostics seen but not expected: 
  File C:\src\llvm-project\clang\test\Sema\builtin-assume-aligned.c Line 62: requested alignment must be 8192 bytes or smaller; assumption ignored
2 errors generated.

error: command failed with exit status: 1

--

********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
Testing Time: 152.23s
********************
Failing Tests (1):
    Clang :: Sema/builtin-assume-aligned.c

Since you just left IRC, I reverted this in 374456 for now.

rsmith added a subscriber: rsmith.Oct 10 2019, 2:46 PM

This seems to be missing a CodeGen test for what IR we generate on an overly-large alignment. (The warning says the alignment is ignored, but I don't see where you're actually doing anything different in that case when generating IR.)

clang/include/clang/Basic/DiagnosticSemaKinds.td
2857–2859

Ignoring the assumption in this case seems unnecessarily user-hostile (and would require hard-coding an arbitrary LLVM limit in the source code to work around). Couldn't we just assume the highest alignment that we do support instead?

clang/lib/CodeGen/CGStmtOpenMP.cpp
1522

It's not appropriate to assume that size_t is any bigger than unsigned or generally that it's meaningful on the target. If you want 64 bits here, use uint64_t, but the right choice is probably llvm::APInt.

clang/lib/Sema/SemaChecking.cpp
6067–6070

Why is there a different limit depending on bin format? We can support this at the IR level regardless, can't we? (I don't see how the binary format is relevant.)

erichkeane marked 5 inline comments as done.Oct 11 2019, 6:10 AM
erichkeane added subscribers: majnemer, aaron.ballman.

This seems to be missing a CodeGen test for what IR we generate on an overly-large alignment. (The warning says the alignment is ignored, but I don't see where you're actually doing anything different in that case when generating IR.)

My intent was to just let the value through, and let LLVM ignore it (while alerting the developer). I'll add a CodeGen test as well when relanding, it seems to have been lost in the process of developing the patch. Thanks for your attention here.

clang/include/clang/Basic/DiagnosticSemaKinds.td
2857–2859

This more closely fit GCCs behavior (of ignoring any invalid value, though their top limit is int64-max). We can definitely just assume highest alignment, I'll do that in my re-land.

clang/lib/Sema/SemaChecking.cpp
6067–6070

I'd copied it from the Sema::AddAlignedAttr implementation, but I cannot seem to figure out the origin of that. @majnemer added the 2**28 business back in 2015, but @aaron.ballman put the limit of 8192 in here: https://reviews.llvm.org/rL158717#change-N0HH8qtBJv7d
(note it was reverted and relanded).

I don't see sufficient justification in that history now that I've looked back to keep that log in here, so I'll keep us at 2**28.

aaron.ballman added inline comments.Oct 13 2019, 12:35 PM
clang/lib/Sema/SemaChecking.cpp
6067–6070

It's been a while, but I seem to recall this matching a behavior of MSVC at the time.

hans added a subscriber: hans.Nov 5 2019, 1:18 AM

We hit this in V8 which is annotating some pointers as being 4GB-aligned. Does anyone know what it would take to raise Clang's limit here?

erichkeane marked 2 inline comments as done.Nov 5 2019, 1:36 AM

We hit this in V8 which is annotating some pointers as being 4GB-aligned. Does anyone know what it would take to raise Clang's limit here?

The issue is LLVM's limit here. I'm unaware of the reasoning for this limit in LLVM, however the clang limit is based on LLVMs. I'd suggest starting a conversation on llvm-dev mailing list to have the discussion of why this limit exists, and whether it is modifiable.