[llvm-branch-commits] [clang] [CIR] Split CIR_UnaryOp into individual operations (PR #185280)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Mar 8 07:13:17 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
@llvm/pr-subscribers-clang
Author: Henrich Lauko (xlauko)
<details>
<summary>Changes</summary>
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
---
Patch is 487.81 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/185280.diff
82 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+18-5)
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+111-28)
- (modified) clang/include/clang/CIR/Interfaces/CIROpInterfaces.td (+21)
- (modified) clang/lib/CIR/CodeGen/CIRGenBuilder.h (+2-4)
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp (+2-4)
- (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+5-8)
- (modified) clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp (+11-17)
- (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+31-40)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+2-4)
- (modified) clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp (+4-7)
- (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+56-88)
- (modified) clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp (+6-6)
- (modified) clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp (+3-4)
- (modified) clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp (+26-33)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+90-104)
- (modified) clang/test/CIR/CodeGen/atomic.c (+14-14)
- (modified) clang/test/CIR/CodeGen/bitfields.c (+1-1)
- (modified) clang/test/CIR/CodeGen/complex-builtins.cpp (+1-1)
- (modified) clang/test/CIR/CodeGen/complex-unary.cpp (+22-26)
- (modified) clang/test/CIR/CodeGen/cxx-rewritten-binary-operator.cpp (+1-1)
- (modified) clang/test/CIR/CodeGen/dynamic-cast-exact.cpp (+1-1)
- (modified) clang/test/CIR/CodeGen/fold-during-cg.c (+35-35)
- (modified) clang/test/CIR/CodeGen/integer-overflow.c (+14-14)
- (modified) clang/test/CIR/CodeGen/label.c (+1-1)
- (modified) clang/test/CIR/CodeGen/lambda-static-invoker.cpp (-1)
- (modified) clang/test/CIR/CodeGen/nrvo.cpp (+1-1)
- (modified) clang/test/CIR/CodeGen/pointers.cpp (+1-1)
- (modified) clang/test/CIR/CodeGen/static-vars.c (+1-1)
- (modified) clang/test/CIR/CodeGen/static-vars.cpp (+1-1)
- (modified) clang/test/CIR/CodeGen/try-catch.cpp (+2-2)
- (modified) clang/test/CIR/CodeGen/unary.cpp (+26-31)
- (modified) clang/test/CIR/CodeGen/vector-ext.cpp (+2-2)
- (modified) clang/test/CIR/CodeGen/vector.cpp (+2-2)
- (modified) clang/test/CIR/CodeGen/vla.c (+1-1)
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx512bw-builtins.c (+6-6)
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx512dq-builtins.c (+3-3)
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c (+3-3)
- (modified) clang/test/CIR/CodeGenBuiltins/builtin-fcmp-sse.c (+4-4)
- (modified) clang/test/CIR/CodeGenBuiltins/builtin-types-compatible.c (+1-1)
- (modified) clang/test/CIR/CodeGenOpenACC/atomic-capture.cpp (+12-12)
- (modified) clang/test/CIR/CodeGenOpenACC/atomic-update.cpp (+3-3)
- (modified) clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp (+7-7)
- (modified) clang/test/CIR/CodeGenOpenACC/combined-private-clause.cpp (+2-2)
- (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp (+27-27)
- (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-float.cpp (+18-18)
- (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-inline-ops.cpp (+36-36)
- (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-int.cpp (+27-27)
- (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-outline-ops.cpp (+36-36)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.c (+3-3)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp (+7-7)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-private-clause.cpp (+2-2)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-default-ops.c (+27-27)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-default-ops.cpp (+27-27)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-float.c (+18-18)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-float.cpp (+18-18)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-inline-ops.cpp (+36-36)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-int.c (+27-27)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-int.cpp (+27-27)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-outline-ops.cpp (+36-36)
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-unsigned-int.c (+27-27)
- (modified) clang/test/CIR/CodeGenOpenACC/data.c (+2-2)
- (modified) clang/test/CIR/CodeGenOpenACC/firstprivate-clause-recipes.cpp (+23-23)
- (modified) clang/test/CIR/CodeGenOpenACC/loop-private-clause.cpp (+2-2)
- (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-default-ops.cpp (+27-27)
- (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-float.cpp (+18-18)
- (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-inline-ops.cpp (+36-36)
- (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-int.cpp (+27-27)
- (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-outline-ops.cpp (+36-36)
- (modified) clang/test/CIR/CodeGenOpenACC/private-clause-array-recipes-CtorDtor.cpp (+16-16)
- (modified) clang/test/CIR/CodeGenOpenACC/private-clause-array-recipes-NoOps.cpp (+8-8)
- (modified) clang/test/CIR/CodeGenOpenACC/private-clause-pointer-array-recipes-CtorDtor.cpp (+62-62)
- (modified) clang/test/CIR/CodeGenOpenACC/private-clause-pointer-array-recipes-NoOps.cpp (+41-41)
- (modified) clang/test/CIR/CodeGenOpenACC/private-clause-pointer-array-recipes-int.cpp (+20-20)
- (modified) clang/test/CIR/CodeGenOpenACC/private-clause-pointer-recipes-CtorDtor.cpp (+22-22)
- (modified) clang/test/CIR/CodeGenOpenACC/private-clause-pointer-recipes-NoOps.cpp (+16-16)
- (modified) clang/test/CIR/CodeGenOpenACC/private-clause-pointer-recipes-int.cpp (+10-10)
- (modified) clang/test/CIR/CodeGenOpenACC/reduction-clause-recipes.cpp (+32-32)
- (modified) clang/test/CIR/IR/unary.cir (+16-16)
- (modified) clang/test/CIR/Transforms/canonicalize.cir (+15-15)
- (modified) clang/test/CIR/Transforms/flatten-cleanup-scope-eh.cir (+3-3)
- (modified) clang/test/CIR/Transforms/flatten-cleanup-scope-multi-exit.cir (+2-2)
- (modified) clang/test/CIR/Transforms/select.cir (+1-1)
``````````diff
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index f51bea894d2ae..88d7042410b45 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -231,9 +231,12 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return createLoad(loc, ptr, /*isVolatile=*/false, alignment);
}
+ mlir::Value createNot(mlir::Location loc, mlir::Value value) {
+ return cir::NotOp::create(*this, loc, value);
+ }
+
mlir::Value createNot(mlir::Value value) {
- return cir::UnaryOp::create(*this, value.getLoc(), value.getType(),
- cir::UnaryOpKind::Not, value);
+ return createNot(value.getLoc(), value);
}
/// Create a do-while operation.
@@ -272,9 +275,19 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return cir::ContinueOp::create(*this, loc);
}
- mlir::Value createUnaryOp(mlir::Location loc, cir::UnaryOpKind kind,
- mlir::Value operand) {
- return cir::UnaryOp::create(*this, loc, kind, operand);
+ mlir::Value createInc(mlir::Location loc, mlir::Value input,
+ bool nsw = false) {
+ return cir::IncOp::create(*this, loc, input, nsw);
+ }
+
+ mlir::Value createDec(mlir::Location loc, mlir::Value input,
+ bool nsw = false) {
+ return cir::DecOp::create(*this, loc, input, nsw);
+ }
+
+ mlir::Value createMinus(mlir::Location loc, mlir::Value input,
+ bool nsw = false) {
+ return cir::MinusOp::create(*this, loc, input, nsw);
}
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value) {
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 625ee1fdea4a2..e3a0508cab0df 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1703,49 +1703,132 @@ def CIR_LabelOp : CIR_Op<"label", [AlwaysSpeculatable]> {
}
//===----------------------------------------------------------------------===//
-// UnaryOp
+// Unary Operations
//===----------------------------------------------------------------------===//
-def CIR_UnaryOpKind : CIR_I32EnumAttr<"UnaryOpKind", "unary operation kind", [
- I32EnumAttrCase<"Inc", 0, "inc">,
- I32EnumAttrCase<"Dec", 1, "dec">,
- I32EnumAttrCase<"Minus", 2, "minus">,
- I32EnumAttrCase<"Not", 3, "not">
-]>;
+// Base class for all CIR unary operations.
+// `type` constrains the input/result type.
+class CIR_UnaryOp<string mnemonic, Type type, list<Trait> traits = []>
+ : CIR_Op<mnemonic, !listconcat([
+ Pure, SameOperandsAndResultType,
+ DeclareOpInterfaceMethods<CIR_UnaryOpInterface>
+ ], traits)>
+{
+ let arguments = (ins type:$input);
+
+ let results = (outs type:$result);
+
+ let assemblyFormat = [{
+ $input `:` type($input) attr-dict
+ }];
+}
+
+// Base class for unary ops that support the nsw (no signed wrap) flag.
+class CIR_UnaryOpWithOverflowFlag<string mnemonic, Type type,
+ list<Trait> traits = []>
+ : CIR_UnaryOp<mnemonic, type, traits>
+{
+ let arguments = (ins type:$input, UnitProp:$no_signed_wrap);
+
+ let assemblyFormat = [{
+ (`nsw` $no_signed_wrap^)?
+ $input `:` type($input) attr-dict
+ }];
+}
-def CIR_UnaryOp : CIR_Op<"unary", [Pure, SameOperandsAndResultType]> {
- let summary = "Unary operations";
+//===----------------------------------------------------------------------===//
+// IncOp
+//===----------------------------------------------------------------------===//
+
+def CIR_IncOp : CIR_UnaryOpWithOverflowFlag<"inc", CIR_AnyType> {
+ let summary = "Increment by one";
let description = [{
- `cir.unary` performs the unary operation according to
- the specified opcode kind: [inc, dec, minus, not].
+ The `cir.inc` operation increments the operand by one. The operand and
+ result must have the same type.
- It requires one input operand and has one result, both types
- should be the same.
+ The optional `nsw` (no signed wrap) attribute indicates that the result
+ is poison if signed overflow occurs.
- If the `nsw` (no signed wrap) attribute is present, the result is poison if
- signed overflow occurs.
+ Example:
```mlir
- %7 = cir.unary(inc, %1) : i32 -> i32
- %8 = cir.unary(dec, %2) nsw : i32 -> i32
+ %1 = cir.inc %0 : !s32i
+ %3 = cir.inc nsw %2 : !s32i
```
}];
- let arguments = (ins
- Arg<CIR_UnaryOpKind, "unary op kind">:$kind,
- Arg<CIR_AnyType>:$input,
- UnitAttr:$no_signed_wrap
- );
+ let hasFolder = 1;
+}
- let results = (outs CIR_AnyType:$result);
+//===----------------------------------------------------------------------===//
+// DecOp
+//===----------------------------------------------------------------------===//
- let assemblyFormat = [{
- `(` $kind `,` $input `)`
- (`nsw` $no_signed_wrap^)?
- `:` type($input) `,` type($result) attr-dict
+def CIR_DecOp : CIR_UnaryOpWithOverflowFlag<"dec", CIR_AnyType> {
+ let summary = "Decrement by one";
+ let description = [{
+ The `cir.dec` operation decrements the operand by one. The operand and
+ result must have the same type.
+
+ The optional `nsw` (no signed wrap) attribute indicates that the result
+ is poison if signed overflow occurs.
+
+ Example:
+
+ ```mlir
+ %1 = cir.dec %0 : !s32i
+ %3 = cir.dec nsw %2 : !s32i
+ ```
+ }];
+
+ let hasFolder = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// MinusOp
+//===----------------------------------------------------------------------===//
+
+def CIR_MinusOp : CIR_UnaryOpWithOverflowFlag<"minus", CIR_AnyType> {
+ let summary = "Unary minus (negation)";
+ let description = [{
+ The `cir.minus` operation negates the operand. The operand and result
+ must have the same type.
+
+ The optional `nsw` (no signed wrap) attribute indicates that the result
+ is poison if signed overflow occurs (e.g. negating the minimum signed
+ integer).
+
+ Example:
+
+ ```mlir
+ %1 = cir.minus %0 : !s32i
+ %3 = cir.minus nsw %2 : !s32i
+ %5 = cir.minus %4 : !cir.float
+ ```
+ }];
+
+ let hasFolder = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// NotOp
+//===----------------------------------------------------------------------===//
+
+def CIR_NotOp : CIR_UnaryOp<"not", CIR_AnyType, [Involution]> {
+ let summary = "Bitwise NOT / logical NOT";
+ let description = [{
+ The `cir.not` operation performs a bitwise NOT on integer types or a
+ logical NOT on boolean types. The operand and result must have the same
+ type.
+
+ Example:
+
+ ```mlir
+ %1 = cir.not %0 : !s32i
+ %3 = cir.not %2 : !cir.bool
+ ```
}];
- let hasVerifier = 1;
let hasFolder = 1;
}
diff --git a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
index c715e2e03a7b9..41885d4df8f20 100644
--- a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
+++ b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
@@ -189,6 +189,27 @@ let cppNamespace = "::cir" in {
];
}
+ def CIR_UnaryOpInterface : OpInterface<"UnaryOpInterface"> {
+ let description = [{
+ Common interface for CIR unary operations.
+ Provides uniform access to the input operand and result of any unary
+ operation in the CIR dialect.
+ }];
+
+ let methods = [
+ InterfaceMethod<"Return the input operand.",
+ "mlir::Value", "getInput", (ins), [{}],
+ /*defaultImplementation=*/[{
+ return $_op.getInput();
+ }]>,
+ InterfaceMethod<"Return the result value.",
+ "mlir::Value", "getResult", (ins), [{}],
+ /*defaultImplementation=*/[{
+ return $_op.getResult();
+ }]>,
+ ];
+ }
+
} // namespace cir
#endif // CLANG_CIR_INTERFACES_CIROPINTERFACES_TD
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index e2f89cc5aa12f..be21e3f29f879 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -429,8 +429,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
// Source is a unsigned integer: first cast it to signed.
if (intTy.isUnsigned())
value = createIntCast(value, getSIntNTy(intTy.getWidth()));
- return cir::UnaryOp::create(*this, value.getLoc(), value.getType(),
- cir::UnaryOpKind::Minus, value);
+ return createMinus(value.getLoc(), value);
}
llvm_unreachable("negation for the given type is NYI");
@@ -444,8 +443,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
assert(!cir::MissingFeatures::fpConstraints());
assert(!cir::MissingFeatures::fastMathFlags());
- return cir::UnaryOp::create(*this, value.getLoc(), value.getType(),
- cir::UnaryOpKind::Minus, value);
+ return createMinus(value.getLoc(), value);
}
//===--------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 244979aac917e..1b59dc16cafb6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -182,8 +182,7 @@ static RValue emitBinaryAtomicPost(CIRGenFunction &cgf,
result = BinOp::create(builder, result.getLoc(), result, emittedArgValue);
if (invert)
- result = cir::UnaryOp::create(builder, result.getLoc(),
- cir::UnaryOpKind::Not, result);
+ result = builder.createNot(result);
result = emitFromInt(cgf, result, typ, originalArgType);
return RValue::get(result);
@@ -1085,8 +1084,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
case Builtin::BIconjf:
case Builtin::BIconjl: {
mlir::Value complex = emitComplexExpr(e->getArg(0));
- mlir::Value conj = builder.createUnaryOp(getLoc(e->getExprLoc()),
- cir::UnaryOpKind::Not, complex);
+ mlir::Value conj = builder.createNot(complex);
return RValue::getComplex(conj);
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 51dc297e86d01..3d6e32085cc83 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -218,7 +218,7 @@ Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
// Unary &
if (const UnaryOperator *uo = dyn_cast<UnaryOperator>(expr)) {
- // TODO(cir): maybe we should use cir.unary for pointers here instead.
+ // TODO(cir): maybe we should use a CIR unary op for pointers here instead.
if (uo->getOpcode() == UO_AddrOf) {
LValue lv = emitLValue(uo->getSubExpr());
if (baseInfo)
@@ -1052,17 +1052,14 @@ LValue CIRGenFunction::emitUnaryOpLValue(const UnaryOperator *e) {
}
case UO_PreInc:
case UO_PreDec: {
- cir::UnaryOpKind kind =
- e->isIncrementOp() ? cir::UnaryOpKind::Inc : cir::UnaryOpKind::Dec;
LValue lv = emitLValue(e->getSubExpr());
assert(e->isPrefix() && "Prefix operator in unexpected state!");
- if (e->getType()->isAnyComplexType()) {
- emitComplexPrePostIncDec(e, lv, kind, /*isPre=*/true);
- } else {
- emitScalarPrePostIncDec(e, lv, kind, /*isPre=*/true);
- }
+ if (e->getType()->isAnyComplexType())
+ emitComplexPrePostIncDec(e, lv);
+ else
+ emitScalarPrePostIncDec(e, lv);
return lv;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 1d05f03491d40..7d302030ccf50 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -173,22 +173,21 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
mlir::Value VisitStmtExpr(const StmtExpr *e);
// Operators.
- mlir::Value VisitPrePostIncDec(const UnaryOperator *e, cir::UnaryOpKind op,
- bool isPre) {
+ mlir::Value VisitPrePostIncDec(const UnaryOperator *e) {
LValue lv = cgf.emitLValue(e->getSubExpr());
- return cgf.emitComplexPrePostIncDec(e, lv, op, isPre);
+ return cgf.emitComplexPrePostIncDec(e, lv);
}
mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {
- return VisitPrePostIncDec(e, cir::UnaryOpKind::Dec, false);
+ return VisitPrePostIncDec(e);
}
mlir::Value VisitUnaryPostInc(const UnaryOperator *e) {
- return VisitPrePostIncDec(e, cir::UnaryOpKind::Inc, false);
+ return VisitPrePostIncDec(e);
}
mlir::Value VisitUnaryPreDec(const UnaryOperator *e) {
- return VisitPrePostIncDec(e, cir::UnaryOpKind::Dec, true);
+ return VisitPrePostIncDec(e);
}
mlir::Value VisitUnaryPreInc(const UnaryOperator *e) {
- return VisitPrePostIncDec(e, cir::UnaryOpKind::Inc, true);
+ return VisitPrePostIncDec(e);
}
mlir::Value VisitUnaryDeref(const Expr *e) { return emitLoadOfLValue(e); }
@@ -602,8 +601,7 @@ mlir::Value ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *e,
op = cgf.emitPromotedComplexExpr(e->getSubExpr(), promotionType);
else
op = Visit(e->getSubExpr());
- return builder.createUnaryOp(cgf.getLoc(e->getExprLoc()),
- cir::UnaryOpKind::Minus, op);
+ return builder.createMinus(cgf.getLoc(e->getExprLoc()), op);
}
mlir::Value ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *e) {
@@ -1095,15 +1093,11 @@ LValue CIRGenFunction::emitComplexCompoundAssignmentLValue(
}
mlir::Value CIRGenFunction::emitComplexPrePostIncDec(const UnaryOperator *e,
- LValue lv,
- cir::UnaryOpKind op,
- bool isPre) {
- assert((op == cir::UnaryOpKind::Inc || op == cir::UnaryOpKind::Dec) &&
- "Invalid UnaryOp kind for ComplexType");
-
+ LValue lv) {
mlir::Value inVal = emitLoadOfComplex(lv, e->getExprLoc());
mlir::Location loc = getLoc(e->getExprLoc());
- mlir::Value incVal = builder.createUnaryOp(loc, op, inVal);
+ mlir::Value incVal = e->isIncrementOp() ? builder.createInc(loc, inVal)
+ : builder.createDec(loc, inVal);
// Store the updated result through the lvalue.
emitStoreOfComplex(loc, incVal, lv, /*isInit=*/false);
@@ -1113,7 +1107,7 @@ mlir::Value CIRGenFunction::emitComplexPrePostIncDec(const UnaryOperator *e,
// If this is a postinc, return the value read from memory, otherwise use the
// updated value.
- return isPre ? incVal : inVal;
+ return e->isPrefix() ? incVal : inVal;
}
LValue CIRGenFunction::emitScalarCompoundAssignWithComplex(
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 29aa35e762f45..711d921e4c79f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -586,24 +586,23 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
VisitAbstractConditionalOperator(const AbstractConditionalOperator *e);
// Unary Operators.
- mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {
+ mlir::Value VisitUnaryPrePostIncDec(const UnaryOperator *e) {
LValue lv = cgf.emitLValue(e->getSubExpr());
- return emitScalarPrePostIncDec(e, lv, cir::UnaryOpKind::Dec, false);
+ return emitScalarPrePostIncDec(e, lv);
+ }
+ mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {
+ return VisitUnaryPrePostIncDec(e);
}
mlir::Value VisitUnaryPostInc(const UnaryOperator *e) {
- LValue lv = cgf.emitLValue(e->getSubExpr());
- return emitScalarPrePostIncDec(e, lv, cir::UnaryOpKind::Inc, false);
+ return VisitUnaryPrePostIncDec(e);
}
mlir::Value VisitUnaryPreDec(const UnaryOperator *e) {
- LValue lv = cgf.emitLValue(e->getSubExpr());
- return emitScalarPrePostIncDec(e, lv, cir::UnaryOpKind::Dec, true);
+ return VisitUnaryPrePostIncDec(e);
}
mlir::Value VisitUnaryPreInc(const UnaryOperator *e) {
- LValue lv = cgf.emitLValue(e->getSubExpr());
- return emitScalarPrePostIncDec(e, lv, cir::UnaryOpKind::Inc, true);
+ return VisitUnaryPrePostIncDec(e);
}
- mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv,
- cir::UnaryOpKind kind, bool isPre) {
+ mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv) {
if (cgf.getLangOpts().OpenMP)
cgf.cgm.errorNYI(e->getSourceRange(), "inc/dec OpenMP");
@@ -632,7 +631,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
// -> bool = ((int)bool + 1 != 0)
// An interesting aspect of this is that increment is always true.
// Decrement does not have this property.
- if (kind == cir::UnaryOpKind::Inc && type->isBooleanType()) {
+ if (e->isIncrementOp() && type->isBooleanType()) {
value = builder.getTrue(cgf.getLoc(e->getExprLoc()));
} else if (type->isIntegerType()) {
QualType promotedType;
@@ -663,12 +662,10 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
assert(!cir::MissingFeatures::sanitizers());
if (e->canOverflow() && type->isSignedIntegerOrEnumerationType()) {
- value = emitIncDecConsiderOverflowBehavior(e, value, kind);
+ value = emitIncDecConsiderOverflowBehavior(e, value);
} else {
- cir::UnaryOpKind kind =
- e->isIncrementOp() ? cir::UnaryOpKind::Inc : cir::UnaryOpKind::Dec;
// NOTE(CIR): clang calls CreateAdd but folds this to a unary op
- value = emitUnaryOp(e, kind, input, /*nsw=*/false);
+ value = emitIncOrDec(e, input, /*nsw=*/false);
}
} else if (const PointerType *ptr = type->getAs<PointerType>()) {
QualType type = ptr->getPointeeType();
@@ -680,7 +677,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
// For everything else, we can just do a simple increment.
mlir::Location loc = cgf.getLoc(e->getSourceRange());
CIRGenBuilderTy &builder = cgf.getBuilder();
- int amount = kind == cir::UnaryOpKind::Inc ? 1 : -1;
+ int amount = e->isIncrementOp() ? 1 : -1;
mlir::Value amt = builder.getSInt32(amount, loc);
assert(!cir::MissingFeatures::sanitizers());
value = builder.createPtrStride(loc, value, amt);
@@ -700,10 +697,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
if (mlir::isa<cir::SingleType, cir::DoubleType>(value.getType())) {
// Create the inc/dec operation.
// NOTE(CIR): clang calls CreateAdd but folds this to a unary op
- assert(
- (kind == cir::UnaryOpKind::Inc || kind == cir::UnaryOpKind::Dec) &&
- "Invalid UnaryOp kind");
- value = emitUnaryOp(e, kind, value);
+ value = emitIncOrDec(e, value);
} else {
cgf.cgm.errorNYI(e->getSourceRange(), "Unary inc/dec other fp type");
return {};
@@ -728,23 +722,20 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
// If this is a postinc, return the value read from memory, otherwise use
// the updated value.
- return isPre ? value : input;
+ return e->isPrefix() ? value : input;
}
mlir::Value emitIncDecConsiderOverflowBehavior(const UnaryOperator *e,
- mlir::Value inVal,
- cir::UnaryOpKind kind) {
- assert((kind == cir::UnaryOpKind::Inc || kind == cir::UnaryOpKind::Dec) &&
- "Invalid UnaryOp kind");
+ mlir::Value inVal) {
switch (cgf.getLangOpts().getSignedOverflowBehavior()) {
case LangOptions::SOB_Defined:
- return emitUnaryOp(e, kind, inVal, /*nsw=*/false);
+ return emitIncOrDec(e, inVal, /*nsw=*/false);
case LangOptions::SOB_Undefined:
assert(!cir::MissingFeatures::sanitizers());
...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/185280
More information about the llvm-branch-commits
mailing list