Skip to content

Commit abdf5a2

Browse files
authored
Merge branch 'main' into users/kparzysz/spr/d02-clang-parser
2 parents 49ef393 + 795b17d commit abdf5a2

File tree

78 files changed

+4054
-557
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+4054
-557
lines changed

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -228,25 +228,28 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
228228

229229
cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
230230
mlir::Type returnType, mlir::ValueRange operands,
231-
cir::SideEffect sideEffect = cir::SideEffect::All) {
232-
return create<cir::CallOp>(loc, callee, returnType, operands, sideEffect);
231+
llvm::ArrayRef<mlir::NamedAttribute> attrs = {}) {
232+
auto op = create<cir::CallOp>(loc, callee, returnType, operands);
233+
op->setAttrs(attrs);
234+
return op;
233235
}
234236

235237
cir::CallOp createCallOp(mlir::Location loc, cir::FuncOp callee,
236238
mlir::ValueRange operands,
237-
cir::SideEffect sideEffect = cir::SideEffect::All) {
239+
llvm::ArrayRef<mlir::NamedAttribute> attrs = {}) {
238240
return createCallOp(loc, mlir::SymbolRefAttr::get(callee),
239241
callee.getFunctionType().getReturnType(), operands,
240-
sideEffect);
242+
attrs);
241243
}
242244

243-
cir::CallOp createIndirectCallOp(mlir::Location loc,
244-
mlir::Value indirectTarget,
245-
cir::FuncType funcType,
246-
mlir::ValueRange operands,
247-
cir::SideEffect sideEffect) {
248-
return create<cir::CallOp>(loc, indirectTarget, funcType.getReturnType(),
249-
operands, sideEffect);
245+
cir::CallOp
246+
createIndirectCallOp(mlir::Location loc, mlir::Value indirectTarget,
247+
cir::FuncType funcType, mlir::ValueRange operands,
248+
llvm::ArrayRef<mlir::NamedAttribute> attrs = {}) {
249+
llvm::SmallVector<mlir::Value> resOperands{indirectTarget};
250+
resOperands.append(operands.begin(), operands.end());
251+
return createCallOp(loc, mlir::SymbolRefAttr(), funcType.getReturnType(),
252+
resOperands, attrs);
250253
}
251254

252255
//===--------------------------------------------------------------------===//

clang/include/clang/CIR/Dialect/IR/CIRDialect.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ def CIR_Dialect : Dialect {
3737
let extraClassDeclaration = [{
3838
static llvm::StringRef getTripleAttrName() { return "cir.triple"; }
3939
static llvm::StringRef getOptInfoAttrName() { return "cir.opt_info"; }
40+
static llvm::StringRef getCalleeAttrName() { return "callee"; }
41+
static llvm::StringRef getNoThrowAttrName() { return "nothrow"; }
42+
static llvm::StringRef getSideEffectAttrName() { return "side_effect"; }
4043

4144
void registerAttributes();
4245
void registerTypes();

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 145 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1991,6 +1991,7 @@ class CIR_CallOpBase<string mnemonic, list<Trait> extra_traits = []>
19911991

19921992
dag commonArgs = (ins OptionalAttr<FlatSymbolRefAttr>:$callee,
19931993
Variadic<CIR_AnyType>:$args,
1994+
UnitAttr:$nothrow,
19941995
DefaultValuedAttr<CIR_SideEffect, "SideEffect::All">:$side_effect);
19951996
}
19961997

@@ -2020,29 +2021,14 @@ def CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> {
20202021
let arguments = commonArgs;
20212022

20222023
let builders = [
2023-
// Build a call op for a direct call
20242024
OpBuilder<(ins "mlir::SymbolRefAttr":$callee, "mlir::Type":$resType,
2025-
"mlir::ValueRange":$operands,
2026-
CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{
2027-
assert(callee && "callee attribute is required for direct call");
2025+
"mlir::ValueRange":$operands), [{
20282026
$_state.addOperands(operands);
2029-
$_state.addAttribute("callee", callee);
2030-
$_state.addAttribute("side_effect",
2031-
SideEffectAttr::get($_builder.getContext(), sideEffect));
2027+
if (callee)
2028+
$_state.addAttribute("callee", callee);
20322029
if (resType && !isa<VoidType>(resType))
20332030
$_state.addTypes(resType);
2034-
}]>,
2035-
// Build a call op for an indirect call
2036-
OpBuilder<(ins "mlir::Value":$calleePtr, "mlir::Type":$resType,
2037-
"mlir::ValueRange":$operands,
2038-
CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{
2039-
$_state.addOperands(calleePtr);
2040-
$_state.addOperands(operands);
2041-
if (resType && !isa<VoidType>(resType))
2042-
$_state.addTypes(resType);
2043-
$_state.addAttribute("side_effect",
2044-
SideEffectAttr::get($_builder.getContext(), sideEffect));
2045-
}]>,
2031+
}]>
20462032
];
20472033
}
20482034

@@ -2535,6 +2521,146 @@ def ComplexImagOp : CIR_Op<"complex.imag", [Pure]> {
25352521
let hasFolder = 1;
25362522
}
25372523

2524+
//===----------------------------------------------------------------------===//
2525+
// Bit Manipulation Operations
2526+
//===----------------------------------------------------------------------===//
2527+
2528+
class CIR_BitOpBase<string mnemonic, TypeConstraint operandTy>
2529+
: CIR_Op<mnemonic, [Pure, SameOperandsAndResultType]> {
2530+
let arguments = (ins operandTy:$input);
2531+
let results = (outs operandTy:$result);
2532+
2533+
let assemblyFormat = [{
2534+
`(` $input `:` type($input) `)` `:` type($result) attr-dict
2535+
}];
2536+
}
2537+
2538+
class CIR_BitZeroCountOpBase<string mnemonic, TypeConstraint operandTy>
2539+
: CIR_BitOpBase<mnemonic, operandTy> {
2540+
let arguments = (ins operandTy:$input, UnitAttr:$poison_zero);
2541+
2542+
let assemblyFormat = [{
2543+
`(` $input `:` type($input) `)` (`poison_zero` $poison_zero^)?
2544+
`:` type($result) attr-dict
2545+
}];
2546+
}
2547+
2548+
def BitClrsbOp : CIR_BitOpBase<"bit.clrsb", CIR_SIntOfWidths<[32, 64]>> {
2549+
let summary = "Get the number of leading redundant sign bits in the input";
2550+
let description = [{
2551+
Compute the number of leading redundant sign bits in the input integer.
2552+
2553+
The input integer must be a signed integer. The most significant bit of the
2554+
input integer is the sign bit. The `cir.bit.clrsb` operation returns the
2555+
number of consecutive bits following the sign bit that are identical to the
2556+
sign bit.
2557+
2558+
The bit width of the input integer must be either 32 or 64.
2559+
2560+
Examples:
2561+
2562+
```mlir
2563+
// %0 = 0b1101_1110_1010_1101_1011_1110_1110_1111
2564+
%0 = cir.const #cir.int<3735928559> : !s32i
2565+
// %1 will be 1 because there is 1 bit following the most significant bit
2566+
// that is identical to it.
2567+
%1 = cir.bit.clrsb(%0 : !s32i) : !s32i
2568+
2569+
// %2 = 1, 0b0000_0000_0000_0000_0000_0000_0000_0001
2570+
%2 = cir.const #cir.int<1> : !s32i
2571+
// %3 will be 30 because there are 30 consecutive bits following the sign
2572+
// bit that are identical to the sign bit.
2573+
%3 = cir.bit.clrsb(%2 : !s32i) : !s32i
2574+
```
2575+
}];
2576+
}
2577+
2578+
def BitClzOp : CIR_BitZeroCountOpBase<"bit.clz",
2579+
CIR_UIntOfWidths<[16, 32, 64]>> {
2580+
let summary = "Get the number of leading 0-bits in the input";
2581+
let description = [{
2582+
Compute the number of leading 0-bits in the input.
2583+
2584+
The input integer must be an unsigned integer. The `cir.bit.clz` operation
2585+
returns the number of consecutive 0-bits at the most significant bit
2586+
position in the input.
2587+
2588+
If the `poison_zero` attribute is present, this operation will have
2589+
undefined behavior if the input value is 0.
2590+
2591+
Example:
2592+
2593+
```mlir
2594+
// %0 = 0b0000_0000_0000_0000_0000_0000_0000_1000
2595+
%0 = cir.const #cir.int<8> : !u32i
2596+
// %1 will be 28
2597+
%1 = cir.bit.clz(%0 : !u32i) poison_zero : !u32i
2598+
```
2599+
}];
2600+
}
2601+
2602+
def BitCtzOp : CIR_BitZeroCountOpBase<"bit.ctz",
2603+
CIR_UIntOfWidths<[16, 32, 64]>> {
2604+
let summary = "Get the number of trailing 0-bits in the input";
2605+
let description = [{
2606+
Compute the number of trailing 0-bits in the input.
2607+
2608+
The input integer must be an unsigned integer. The `cir.bit.ctz` operation
2609+
counts the number of consecutive 0-bits starting from the least significant
2610+
bit.
2611+
2612+
If the `poison_zero` attribute is present, this operation will have
2613+
undefined behavior if the input value is 0.
2614+
2615+
Example:
2616+
2617+
```mlir
2618+
// %0 = 0b1000
2619+
%0 = cir.const #cir.int<8> : !u32i
2620+
// %1 will be 3
2621+
%1 = cir.bit.ctz(%0 : !u32i) poison_zero : !u32i
2622+
```
2623+
}];
2624+
}
2625+
2626+
def BitParityOp : CIR_BitOpBase<"bit.parity", CIR_UIntOfWidths<[32, 64]>> {
2627+
let summary = "Get the parity of input";
2628+
let description = [{
2629+
Compute the parity of the input. The parity of an integer is the number of
2630+
1-bits in it modulo 2.
2631+
2632+
The input must be an unsigned integer.
2633+
2634+
Example:
2635+
2636+
```mlir
2637+
// %0 = 0x0110_1000
2638+
%0 = cir.const #cir.int<104> : !u32i
2639+
// %1 will be 1 since there are three 1-bits in %0
2640+
%1 = cir.bit.parity(%0 : !u32i) : !u32i
2641+
```
2642+
}];
2643+
}
2644+
2645+
def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
2646+
CIR_UIntOfWidths<[16, 32, 64]>> {
2647+
let summary = "Get the number of 1-bits in input";
2648+
let description = [{
2649+
Compute the number of 1-bits in the input.
2650+
2651+
The input must be an unsigned integer.
2652+
2653+
Example:
2654+
2655+
```mlir
2656+
// %0 = 0x0110_1000
2657+
%0 = cir.const #cir.int<104> : !u32i
2658+
// %1 will be 3 since there are 3 1-bits in %0
2659+
%1 = cir.bit.popcnt(%0 : !u32i) : !u32i
2660+
```
2661+
}];
2662+
}
2663+
25382664
//===----------------------------------------------------------------------===//
25392665
// Assume Operations
25402666
//===----------------------------------------------------------------------===//

clang/include/clang/CIR/Interfaces/CIROpInterfaces.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ let cppNamespace = "::cir" in {
3434
"Return the number of operands, accounts for indirect call or "
3535
"exception info",
3636
"unsigned", "getNumArgOperands", (ins)>,
37+
InterfaceMethod<"Return whether the callee is nothrow",
38+
"bool", "getNothrow", (ins)>,
3739
InterfaceMethod<"Return the side effects of the call operation",
3840
"cir::SideEffect", "getSideEffect", (ins)>,
3941
];

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ struct MissingFeatures {
180180
static bool builtinCall() { return false; }
181181
static bool builtinCallF128() { return false; }
182182
static bool builtinCallMathErrno() { return false; }
183+
static bool builtinCheckKind() { return false; }
183184
static bool cgFPOptionsRAII() { return false; }
184185
static bool cirgenABIInfo() { return false; }
185186
static bool cleanupAfterErrorDiags() { return false; }

clang/include/clang/Sema/DeclSpec.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,8 +1821,8 @@ class DecompositionDeclarator {
18211821
if (DeleteBindings)
18221822
delete[] Bindings;
18231823
else
1824-
llvm::for_each(llvm::MutableArrayRef(Bindings, NumBindings),
1825-
[](Binding &B) { B.Attrs.reset(); });
1824+
for (Binding &B : llvm::MutableArrayRef(Bindings, NumBindings))
1825+
B.Attrs.reset();
18261826
Bindings = nullptr;
18271827
NumBindings = 0;
18281828
DeleteBindings = false;

clang/lib/Basic/DiagnosticIDs.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -832,8 +832,12 @@ bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {
832832
DiagID == diag::err_unavailable_message)
833833
return false;
834834

835-
// Currently we consider all ARC errors as recoverable.
836-
if (isARCDiagnostic(DiagID))
835+
// All ARC errors are currently considered recoverable, with the exception of
836+
// err_arc_may_not_respond. This specific error is treated as unrecoverable
837+
// because sending a message with an unknown selector could lead to crashes
838+
// within CodeGen if the resulting expression is used to initialize a C++
839+
// auto variable, where type deduction is required.
840+
if (isARCDiagnostic(DiagID) && DiagID != diag::err_arc_may_not_respond)
837841
return false;
838842

839843
if (isCodegenABICheckDiagnostic(DiagID))

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,29 @@ static RValue emitLibraryCall(CIRGenFunction &cgf, const FunctionDecl *fd,
3434
return cgf.emitCall(e->getCallee()->getType(), callee, e, ReturnValueSlot());
3535
}
3636

37+
template <typename Op>
38+
static RValue emitBuiltinBitOp(CIRGenFunction &cgf, const CallExpr *e,
39+
bool poisonZero = false) {
40+
assert(!cir::MissingFeatures::builtinCheckKind());
41+
42+
mlir::Value arg = cgf.emitScalarExpr(e->getArg(0));
43+
CIRGenBuilderTy &builder = cgf.getBuilder();
44+
45+
Op op;
46+
if constexpr (std::is_same_v<Op, cir::BitClzOp> ||
47+
std::is_same_v<Op, cir::BitCtzOp>)
48+
op = builder.create<Op>(cgf.getLoc(e->getSourceRange()), arg, poisonZero);
49+
else
50+
op = builder.create<Op>(cgf.getLoc(e->getSourceRange()), arg);
51+
52+
mlir::Value result = op.getResult();
53+
mlir::Type exprTy = cgf.convertType(e->getType());
54+
if (exprTy != result.getType())
55+
result = builder.createIntCast(result, exprTy);
56+
57+
return RValue::get(result);
58+
}
59+
3760
RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
3861
const CallExpr *e,
3962
ReturnValueSlot returnValue) {
@@ -101,6 +124,47 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
101124
return RValue::get(complex);
102125
}
103126

127+
case Builtin::BI__builtin_clrsb:
128+
case Builtin::BI__builtin_clrsbl:
129+
case Builtin::BI__builtin_clrsbll:
130+
return emitBuiltinBitOp<cir::BitClrsbOp>(*this, e);
131+
132+
case Builtin::BI__builtin_ctzs:
133+
case Builtin::BI__builtin_ctz:
134+
case Builtin::BI__builtin_ctzl:
135+
case Builtin::BI__builtin_ctzll:
136+
case Builtin::BI__builtin_ctzg:
137+
assert(!cir::MissingFeatures::builtinCheckKind());
138+
return emitBuiltinBitOp<cir::BitCtzOp>(*this, e, /*poisonZero=*/true);
139+
140+
case Builtin::BI__builtin_clzs:
141+
case Builtin::BI__builtin_clz:
142+
case Builtin::BI__builtin_clzl:
143+
case Builtin::BI__builtin_clzll:
144+
case Builtin::BI__builtin_clzg:
145+
assert(!cir::MissingFeatures::builtinCheckKind());
146+
return emitBuiltinBitOp<cir::BitClzOp>(*this, e, /*poisonZero=*/true);
147+
148+
case Builtin::BI__builtin_parity:
149+
case Builtin::BI__builtin_parityl:
150+
case Builtin::BI__builtin_parityll:
151+
return emitBuiltinBitOp<cir::BitParityOp>(*this, e);
152+
153+
case Builtin::BI__lzcnt16:
154+
case Builtin::BI__lzcnt:
155+
case Builtin::BI__lzcnt64:
156+
assert(!cir::MissingFeatures::builtinCheckKind());
157+
return emitBuiltinBitOp<cir::BitClzOp>(*this, e, /*poisonZero=*/false);
158+
159+
case Builtin::BI__popcnt16:
160+
case Builtin::BI__popcnt:
161+
case Builtin::BI__popcnt64:
162+
case Builtin::BI__builtin_popcount:
163+
case Builtin::BI__builtin_popcountl:
164+
case Builtin::BI__builtin_popcountll:
165+
case Builtin::BI__builtin_popcountg:
166+
return emitBuiltinBitOp<cir::BitPopcountOp>(*this, e);
167+
104168
case Builtin::BI__builtin_expect:
105169
case Builtin::BI__builtin_expect_with_probability: {
106170
mlir::Value argValue = emitScalarExpr(e->getArg(0));

0 commit comments

Comments
 (0)