23 Commits

Author SHA1 Message Date
yabinc
627746581b
Reapply "[clang][CodeGen] Zero init unspecified fields in initializers in C" (#109898) (#110051)
This reverts commit d50eaac12f0cdfe27e942290942b06889ab12a8c. Also fixes
a bug calculating offsets for bit fields in the original patch.
2024-10-14 16:32:24 -07:00
Eli Friedman
d50eaac12f
Revert "[clang][CodeGen] Zero init unspecified fields in initializers in C" (#109898)
Reverts llvm/llvm-project#97121

Causing failures on LNT bots; log shows a crash in
ConstStructBuilder::BuildStruct.
2024-09-24 20:31:54 -07:00
yabinc
7a086e1b2d
[clang][CodeGen] Zero init unspecified fields in initializers in C (#97121)
When an initializer is provided to a variable, the Linux kernel relied
on the compiler to zero-initialize unspecified fields, as clarified in
https://www.spinics.net/lists/netdev/msg1007244.html.

But clang doesn't guarantee this:
1. For a union type, if an empty initializer is given, clang only
   initializes bytes for the first field, left bytes for other (larger)
   fields are marked as undef. Accessing those undef bytes can lead
   to undefined behaviors.
2. For a union type, if an initializer explicitly sets a field, left
   bytes for other (larger) fields are marked as undef.
3. When an initializer is given, clang doesn't zero initialize padding.

So this patch makes the following change:
1. In C, when an initializer is provided for a variable, zero-initialize
   undef and padding fields in the initializer.
2. Document the change in LanguageExtensions.rst.

As suggested in
https://github.com/llvm/llvm-project/issues/78034#issuecomment-2183437928,
the change isn't required by C23, but it's standards conforming to do
so.

Fixes: https://github.com/llvm/llvm-project/issues/97459
2024-09-24 19:06:20 -07:00
Hari Limaye
7eca38ce76
Reland "[clang] Add nuw attribute to GEPs (#105496)" (#107257)
Add nuw attribute to inbounds GEPs where the expression used to form the
GEP is an addition of unsigned indices.

Relands #105496, which was reverted because it exposed a miscompilation
arising from #98608. This is now fixed by #106512.
2024-09-05 16:13:11 +01:00
Vitaly Buka
69437a392e
Revert "[clang] Add nuw attribute to GEPs" (#106343)
Reverts llvm/llvm-project#105496

This patch breaks:
https://lab.llvm.org/buildbot/#/builders/25/builds/1952
https://lab.llvm.org/buildbot/#/builders/52/builds/1775

Somehow output is different with sanitizers.
Maybe non-determinism in the code?
2024-08-28 12:14:04 +02:00
Hari Limaye
3d2fd31c8f
[clang] Add nuw attribute to GEPs (#105496)
Add nuw attribute to inbounds GEPs where the expression used to form the
GEP is an addition of unsigned indices.
2024-08-27 14:20:48 +01:00
Hari Limaye
94473f4db6
[IRBuilder] Generate nuw GEPs for struct member accesses (#99538)
Generate nuw GEPs for struct member accesses, as inbounds + non-negative
implies nuw.

Regression tests are updated using update scripts where possible, and by
find + replace where not.
2024-08-09 13:25:04 +01:00
Mariya Podchishchaeva
9ad72df55c
[clang] Use different memory layout type for _BitInt(N) in LLVM IR (#91364)
There are two problems with _BitInt prior to this patch:
1. For at least some values of N, we cannot use LLVM's iN for the type
of struct elements, array elements, allocas, global variables, and so
on, because the LLVM layout for that type does not match the high-level
layout of _BitInt(N).
Example: Currently for i128:128 targets correct implementation is
possible either for __int128 or for _BitInt(129+) with lowering to iN,
but not both, since we have now correct implementation of __int128 in
place after a21abc7.
When this happens, opaque [M x i8] types used, where M =
sizeof(_BitInt(N)).
2. LLVM doesn't guarantee any particular extension behavior for integer
types that aren't a multiple of 8. For this reason, all _BitInt types
are now have in-memory representation that is a whole number of bytes.
I.e. for example _BitInt(17) now will have memory layout type i32.

This patch also introduces concept of load/store type and adds an API to
CodeGenTypes that returns the IR type that should be used for load and
store operations. This is particularly useful for the case when a
_BitInt ends up having array of bytes as memory layout type. For
_BitInt(N), let M = sizeof(_BitInt(N)), and let BITS = M * 8. Loads and
stores of iM would both (1) produce far better code from the backends
and (2) be far more optimizable by IR passes than loads and stores of [M
x i8].

Fixes https://github.com/llvm/llvm-project/issues/85139
Fixes https://github.com/llvm/llvm-project/issues/83419

---------

Co-authored-by: John McCall <rjmccall@gmail.com>
2024-07-15 09:40:39 +02:00
Mariya Podchishchaeva
7133283835 [clang] Do not attempt to zero-extend _BitInt(1) when not required
`ConvertTypeForMem` doesn't return wider type for _BitInt unless it is
used in a bitfield, so no need to extend when trying to initialize a
global variable.

Fixes https://github.com/llvm/llvm-project/issues/62207

Reviewed By: erichkeane, shafik

Differential Revision: https://reviews.llvm.org/D149436
2023-05-02 08:23:22 -04:00
Nikita Popov
39db5e1ed8 [CodeGen] Convert tests to opaque pointers (NFC)
Conversion performed using the script at:
https://gist.github.com/nikic/98357b71fd67756b0f064c9517b62a34

These are only tests where no manual fixup was required.
2022-10-07 14:22:00 +02:00
Nikita Popov
532dc62b90 [OpaquePtrs][Clang] Add -no-opaque-pointers to tests (NFC)
This adds -no-opaque-pointers to clang tests whose output will
change when opaque pointers are enabled by default. This is
intended to be part of the migration approach described in
https://discourse.llvm.org/t/enabling-opaque-pointers-by-default/61322/9.

The patch has been produced by replacing %clang_cc1 with
%clang_cc1 -no-opaque-pointers for tests that fail with opaque
pointers enabled. Worth noting that this doesn't cover all tests,
there's a remaining ~40 tests not using %clang_cc1 that will need
a followup change.

Differential Revision: https://reviews.llvm.org/D123115
2022-04-07 12:09:47 +02:00
Aaron Ballman
adc402bf3d Use functions with prototypes when appropriate; NFC
A significant number of our tests in C accidentally use functions
without prototypes. This patch converts the function signatures to have
a prototype for the situations where the test is not specific to K&R C
declarations. e.g.,

  void func();

becomes

  void func(void);

This is the eleventh batch of tests being updated (there are a
significant number of other tests left to be updated).
2022-02-15 16:06:43 -05:00
Aaron Ballman
a6cabd9802 Revert fad7e491a0770ac4336934030ac67d77e7af5520 with fixes applied
fad7e491a0770ac4336934030ac67d77e7af5520 was a revert of
86797fdb6f51d32f285e48b6d3e0fc5b8b852734 due to build failures. This
hopefully fixes them.
2022-01-29 08:12:16 -05:00
Jan Korous
fad7e491a0 Revert "Add BITINT_MAXWIDTH support"
This reverts commit 86797fdb6f51d32f285e48b6d3e0fc5b8b852734.

Differential Revision: https://reviews.llvm.org/D117238
2022-01-28 15:18:49 -08:00
Aaron Ballman
86797fdb6f Add BITINT_MAXWIDTH support
Part of the _BitInt feature in C2x
(http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2763.pdf) is a new
macro in limits.h named BITINT_MAXWIDTH that can be used to determine
the maximum width of a bit-precise integer type. This macro must expand
to a value that is at least as large as ULLONG_WIDTH.

This adds an implementation-defined macro named __BITINT_MAXWIDTH__ to
specify that value, which is used by limits.h for the standard macro.

This also limits the maximum bit width to 128 bits because backends do
not currently support all mathematical operations (such as division) on
wider types yet. This maximum is expected to be increased in the future.
2022-01-28 15:04:29 -05:00
Aaron Ballman
6c75ab5f66 Introduce _BitInt, deprecate _ExtInt
WG14 adopted the _ExtInt feature from Clang for C23, but renamed the
type to be _BitInt. This patch does the vast majority of the work to
rename _ExtInt to _BitInt, which accounts for most of its size. The new
type is exposed in older C modes and all C++ modes as a conforming
extension. However, there are functional changes worth calling out:

* Deprecates _ExtInt with a fix-it to help users migrate to _BitInt.
* Updates the mangling for the type.
* Updates the documentation and adds a release note to warn users what
is going on.
* Adds new diagnostics for use of _BitInt to call out when it's used as
a Clang extension or as a pre-C23 compatibility concern.
* Adds new tests for the new diagnostic behaviors.

I want to call out the ABI break specifically. We do not believe that
this break will cause a significant imposition for early adopters of
the feature, and so this is being done as a full break. If it turns out
there are critical uses where recompilation is not an option for some
reason, we can consider using ABI tags to ease the transition.
2021-12-06 12:52:01 -05:00
Craig Topper
2fd180bbb9 [IR] Reduce max supported integer from 2^24-1 to 2^23.
SelectionDAG will promote illegal types up to a power of 2 before
splitting down to a legal type. This will create an IntegerType
with a bit width that must be <= MAX_INT_BITS. This places an
effective upper limit on any type of 2^23 so that we don't try
create a 2^24 type.

I considered putting a fatal error somewhere in the path from
TargetLowering::getTypeConversion down to IntegerType::get, but
limiting the type in IR seemed better.

This breaks backwards compatibility with IR that is using a really
large type. I suspect such IR is going to be very rare due to the
the compile time costs such a type likely incurs.

Prevents the ICE in PR51829.

Reviewed By: efriedma, aaron.ballman

Differential Revision: https://reviews.llvm.org/D109721
2021-09-14 07:52:10 -07:00
Erich Keane
2143a90b34 Fix _ExtInt(1) to be a i1 in memory.
The _ExtInt(1) in getTypeForMem was hitting the bool logic for expanding
to an 8 bit value.  The result was an assert, or store i1 %0, i8* %2, align 1
since the parameter IS an i1.  This patch changes the 'forMem' test to
exclude ext-int from the bool test.
2020-08-05 10:54:51 -07:00
Erich Keane
b5a4deec6a [NFC] Split ext-int calling convention tests into their own file.
I'm currently auditing all of the calling convention implications of
_ExtInt for all platforms, so splitting them up into their own test will
make this a much easier task to organize.
2020-04-29 12:20:21 -07:00
Erich Keane
5a1d9c0f5a Fix x86/x86_64 calling convention for _ExtInt
After speaking with Craig Topper about some recent defects, he pointed
out that _ExtInts should be passed indirectly if larger than the largest
int register, and like ints when smaller than that.  This patch
implements that.

Note that this changed the way vaargs worked quite a bit, but they still
work.

Differential Revision: https://reviews.llvm.org/D78785
2020-04-29 11:04:25 -07:00
Erich Keane
5f0903e9be Reland Implement _ExtInt as an extended int type specifier.
I fixed the LLDB issue, so re-applying the patch.

This reverts commit a4b88c044980337bb14390be654fe76864aa60ec.
2020-04-17 10:45:48 -07:00
Sterling Augustine
a4b88c0449 Revert "Implement _ExtInt as an extended int type specifier."
This reverts commit 61ba1481e200b5b35baa81ffcff81acb678e8508.

I'm reverting this because it breaks the lldb build with
incomplete switch coverage warnings. I would fix it forward,
but am not familiar enough with lldb to determine the correct
fix.

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:3958:11: error: enumeration values 'DependentExtInt' and 'ExtInt' not handled in switch [-Werror,-Wswitch]
  switch (qual_type->getTypeClass()) {
          ^
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4633:11: error: enumeration values 'DependentExtInt' and 'ExtInt' not handled in switch [-Werror,-Wswitch]
  switch (qual_type->getTypeClass()) {
          ^
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4889:11: error: enumeration values 'DependentExtInt' and 'ExtInt' not handled in switch [-Werror,-Wswitch]
  switch (qual_type->getTypeClass()) {
2020-04-17 10:29:40 -07:00
Erich Keane
61ba1481e2 Implement _ExtInt as an extended int type specifier.
Introduction/Motivation:
LLVM-IR supports integers of non-power-of-2 bitwidth, in the iN syntax.
Integers of non-power-of-two aren't particularly interesting or useful
on most hardware, so much so that no language in Clang has been
motivated to expose it before.

However, in the case of FPGA hardware normal integer types where the
full bitwidth isn't used, is extremely wasteful and has severe
performance/space concerns.  Because of this, Intel has introduced this
functionality in the High Level Synthesis compiler[0]
under the name "Arbitrary Precision Integer" (ap_int for short). This
has been extremely useful and effective for our users, permitting them
to optimize their storage and operation space on an architecture where
both can be extremely expensive.

We are proposing upstreaming a more palatable version of this to the
community, in the form of this proposal and accompanying patch.  We are
proposing the syntax _ExtInt(N).  We intend to propose this to the WG14
committee[1], and the underscore-capital seems like the active direction
for a WG14 paper's acceptance.  An alternative that Richard Smith
suggested on the initial review was __int(N), however we believe that
is much less acceptable by WG14.  We considered _Int, however _Int is
used as an identifier in libstdc++ and there is no good way to fall
back to an identifier (since _Int(5) is indistinguishable from an
unnamed initializer of a template type named _Int).

[0]https://www.intel.com/content/www/us/en/software/programmable/quartus-prime/hls-compiler.html)
[1]http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2472.pdf

Differential Revision: https://reviews.llvm.org/D73967
2020-04-17 07:10:57 -07:00