This fixes a few places where MissingFeatures asserts were incorrect,
extends the text of two errorNYI diagnostics to disambiguate them, and
fixes a typo in an adjacent comment.
We added those checks when CleanupScopeOp is used to emit an error
message in this edge case until we fix it. Now it's already fixed, and
we don't need to keep the NYI
In preperation of actually lowering data members as fields to a record
type, this patch does a minor refactor to make their single current use
have a slightly simpler interface. This will prevent us from having to
copy/paste this later.
Also, this patch removes a pair of now-orphaned builders, instead
preferring to use the ones that come from the parent builder type.
Split the monolithic cir.unary operation (which dispatched on a
UnaryOpKind enum) into four separate operations: cir.inc, cir.dec,
cir.minus, and cir.not.
Changes:
- Add CIR_UnaryOpInterface with getInput()/getResult() methods
- Add CIR_UnaryOp and CIR_UnaryOpWithOverflowFlag base classes
- Define IncOp, DecOp, MinusOp, NotOp with per-op folds
- Add Involution trait to NotOp for not(not(x)) -> x folding
- Replace createUnaryOp() with createInc/Dec/Minus/Not builders
- Split LLVM lowering into four separate patterns
- Split LoweringPrepare complex-type handling per unary op
- Update CIRCanonicalize and CIRSimplify for new op types
- Update all codegen files to use bool params instead of UnaryOpKind
- Remove CIR_UnaryOpKind enum and old CIR_UnaryOp definition
Assembly format change:
cir.unary(inc, %x) nsw : !s32i, !s32i -> cir.inc nsw %x : !s32i
cir.unary(not, %x) : !u32i, !u32i -> cir.not %x : !u32i
Traditional codegen never emits any operation for unary plus — it just
visits the subexpression as a pure identity at the codegen level. Align
CIRGen with this behavior by removing Plus from UnaryOpKind entirely
and having VisitUnaryPlus directly visit the subexpression with the
appropriate promotion/demotion handling.
Due to && binding tighter than ||, asserts of the form
assert(A || B && "msg") always pass when A is true. Add
parentheses so the string message is properly attached:
assert((A || B) && "msg").
Replace the single `cir.binop` operation (dispatched via a `BinOpKind`
enum) with nine distinct ops — `cir.add`, `cir.sub`, `cir.mul`,
`cir.div`, `cir.rem`, `cir.and`, `cir.or`, `cir.xor`, and `cir.max` —
each with precise type constraints and only the attributes it needs
(nsw/nuw/sat on add/sub via `BinaryOverflowOp`).
A new `BinaryOpInterface` provides uniform `getLhs`/`getRhs`/`getResult`
access for passes and analyses.
The monolithic switch-based CIRToLLVMBinOpLowering is replaced by per-op
patterns generated through the existing CIRLowering.inc TableGen
infrastructure, with shared dispatch factored into two helpers:
`lowerSaturatableArithOp` for add/sub and `lowerIntFPBinaryOp` for
div/rem.
As a GNU extension, clang supports math on void* and function pointers
in C mode only. From a CIR perspective, it makes sense to leave these
types in the IR, since it might be useful to do analysis.
During lowering, we already properly lower these to a size-1 element, so
there is no changes that need to happen besides letting this get through
CIR generation. This patch does that, plus adds some tests.
Update bitfield-assignment codegen to emit stores at
assignment-expression source locations.
Keep `cir.set_bitfield` aligned with other store-like operations.
Prevent regressions that reattach bitfield stores to declaration-site
locations.
Add a CIR test on `clang/test/CIR/CodeGen/bitfield-assignment-loc.c`.
Fix https://github.com/llvm/llvm-project/issues/183759
We currently encounter dominance verification errors when a value is
defined inside a cleanup scope but used outside the scope. This occurs
when forceCleanup() is used to exit a cleanup scope while a variable is
holding a value that was created in the scope body. Classic codegen
solved this problem by passing a list of values to spill and reload to
forceCleanup(). This change implements that same solution for CIR.
I have also aligned the ScalarExprEmitter::VisitExprWithCleanups
implementation with that of classic codegen, eliminating an extra
lexical scope. This causes temporary allocas to be created at the next
higher existing lexical scope, but I think that's OK since they would be
hoisted there anyway by a later pass.
MRE:
```cpp
#include <vector>
std::vector<int> V;
```
```shell
$ ./bin/clang++ -fclangir -c test.cpp
error: ClangIR code gen Not Yet Implemented: ScalarExprEmitter: implicit value init
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
....
```
This PR fixes the crash by upstreaming:
c1e076e803/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (L397-L399)
Previously, we perform nq comparison between LHS, RHS, and zero attr
with the type of the logical Op, but in the case of a vector with FP
element type, the verifier will fail because we perform a comparison of
a vector of FP and a vector of int (the result type of the logical op in
this case is vector of int)
As support for RAII FP options has been upstreamed (#179121), this patch
removes `CIRGenFPOptionsRAII` from the `MissingFeatures` list and
updates its expected constructor sites.
This is just a compile time constant, so we just have to make sure we
get the value and lower it in the correct type, otherwise this is a
fairly trivial task.
There were some cases when compiling a C program where
VisitTypeTraitExpr would return a cir.bool value for a TypeTraitExpr
that required an integer. This was happening because we were checking
`e->isStoredAsBoolean` which returns a result that is inconsistent with
the expression type for C compilation units.
This change fixes the handling and also adds support for other
non-boolean type trait expressions.
fixes#159438
This patch adds `MatrixElementExpr`, a new AST node for HLSL matrix
element and swizzle access (e.g. M._m00, M._11_22_33).
It introduces a shared `ElementAccessExprBase` used by both matrix and
vector swizzle expressions, updates Sema to parse and validate
zero-based and one-based accessors, detects duplicates for l-value
checks, and emits improved diagnostics. CodeGen is updated to lower
scalar and multi-element accesses consistently, and full AST
serialization, dumping, and tooling support is included. This
implementation reflects the updated
[RFC](https://github.com/llvm/wg-hlsl/pull/357/files) for HLSL matrix
accessor semantics.
The conversion code always ended up just getting the type of Src from
the Src argument itself, with no virtual users of this, so there is no
point in also providing this API hook. Fix the documentation as well,
since it seems DestAddr must have been similarly removed at some point
in the past from the API but was still documented.
Also fixes CIR to actually return the casted value!
When the createSub function was added in CIRBaseBuilderTy, the default
for the overflow behavior parameter was set to
OverflowBehavior::Saturated. This led to incorrect behavior for
subtraction when the -fwrapv option was used, but we didn't have a test
for that so it wasn't noticed.
This change adds a test and corrects the behavior.
This adds support in CIR for handling based-to-derived and
derived-to-base casts of pointer-to-member values that point to member
functions.
Co-authored-by: Sirui Mu <msrlancern@gmail.com>
This change upstreams the code to generate CIR for bool casts and
reinterpret casts involving member pointer types and the code to lower
these casts for the Itanium C++ ABI.
This change introduces basic folding of casts and unary ops as they are
created this is needed in order to allow later codegen pieces, such as
builtin handlers, to more easily identify and examine constant operands.
For example, many X86 builtin functions use a default mask operand of
-1, which was previously generated as a constant 1 and a unary minus.
In some cases, the folding process leaves behind unused constant
operations, so I am also added a simple change to the canonicalize pass
to remove unused constants. We had other places where unused constants
were being generated already, and this change cleans those up too.
This adds the CIR basic handling for casts of data member pointers. Cast
to bool and null, as well as member function pointer casts will be
handled in followup PRs.
This adds stubs that issue NYI errors for any visitor that is present in
the ClangIR incubator but missing in the upstream implementation. This
will make it easier to find to correct locations to implement missing
functionality.
This PR upstreams support for the `cir.indirectBr` operation, which is
used to implement GCC’s labels-as-values `indirect goto`.
To ensure correct lowering, we introduce precise bookkeeping to
associate each `block_address` operation with its corresponding `label`
op. This is required because a `block_address` may be emitted before the
`label` it refers to. In such cases, the reference is deferred and later
resolved by `resolveBlockAddresses`, which guarantees that all
`indirectBr` successors are emitted in the correct and fully resolved
order.