Author: Andy Kaylor Date: 2025-04-29T11:31:04-07:00 New Revision: 7d91cf4bab8c9c4daa3d3a9fca87778d6ccacb6b
URL: https://github.com/llvm/llvm-project/commit/7d91cf4bab8c9c4daa3d3a9fca87778d6ccacb6b DIFF: https://github.com/llvm/llvm-project/commit/7d91cf4bab8c9c4daa3d3a9fca87778d6ccacb6b.diff LOG: [CIR] Add support for compound assignment statements (#137740) Compound assignment in C++ goes through a different path than the binary assignment operators that were already handled for C. This change adds the necessary handler to get this working with C++. Added: clang/test/CIR/CodeGen/compound_assign.cpp Modified: clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp clang/lib/CIR/CodeGen/CIRGenFunction.cpp clang/lib/CIR/CodeGen/CIRGenFunction.h Removed: ################################################################################ diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 4ca54940a60b8..aef5b125a2877 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -1010,6 +1010,55 @@ mlir::Value ScalarExprEmitter::emitCompoundAssign( } // namespace +LValue +CIRGenFunction::emitCompoundAssignmentLValue(const CompoundAssignOperator *e) { + ScalarExprEmitter emitter(*this, builder); + mlir::Value result; + switch (e->getOpcode()) { +#define COMPOUND_OP(Op) \ + case BO_##Op##Assign: \ + return emitter.emitCompoundAssignLValue(e, &ScalarExprEmitter::emit##Op, \ + result) + COMPOUND_OP(Mul); + COMPOUND_OP(Div); + COMPOUND_OP(Rem); + COMPOUND_OP(Add); + COMPOUND_OP(Sub); + COMPOUND_OP(Shl); + COMPOUND_OP(Shr); + COMPOUND_OP(And); + COMPOUND_OP(Xor); + COMPOUND_OP(Or); +#undef COMPOUND_OP + + case BO_PtrMemD: + case BO_PtrMemI: + case BO_Mul: + case BO_Div: + case BO_Rem: + case BO_Add: + case BO_Sub: + case BO_Shl: + case BO_Shr: + case BO_LT: + case BO_GT: + case BO_LE: + case BO_GE: + case BO_EQ: + case BO_NE: + case BO_Cmp: + case BO_And: + case BO_Xor: + case BO_Or: + case BO_LAnd: + case BO_LOr: + case BO_Assign: + case BO_Comma: + llvm_unreachable("Not valid compound assignment operators"); + } + llvm_unreachable("Unhandled compound assignment operator"); +} + /// Emit the computation of the specified expression of scalar type. mlir::Value CIRGenFunction::emitScalarExpr(const Expr *e) { assert(e && hasScalarEvaluationKind(e->getType()) && diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp index 5412f9f602711..fa86fce2f6e5c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp @@ -517,6 +517,19 @@ LValue CIRGenFunction::emitLValue(const Expr *e) { return emitMemberExpr(cast<MemberExpr>(e)); case Expr::BinaryOperatorClass: return emitBinaryOperatorLValue(cast<BinaryOperator>(e)); + case Expr::CompoundAssignOperatorClass: { + QualType ty = e->getType(); + if (const AtomicType *at = ty->getAs<AtomicType>()) { + cgm.errorNYI(e->getSourceRange(), + "CompoundAssignOperator with AtomicType"); + return LValue(); + } + if (!ty->isAnyComplexType()) + return emitCompoundAssignmentLValue(cast<CompoundAssignOperator>(e)); + cgm.errorNYI(e->getSourceRange(), + "CompoundAssignOperator with ComplexType"); + return LValue(); + } case Expr::ParenExprClass: return emitLValue(cast<ParenExpr>(e)->getSubExpr()); case Expr::DeclRefExprClass: diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index ec42aee08ee15..592d39930089d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -482,6 +482,8 @@ class CIRGenFunction : public CIRGenTypeCache { mlir::Type condType, bool buildingTopLevelCase); + LValue emitCompoundAssignmentLValue(const clang::CompoundAssignOperator *e); + mlir::LogicalResult emitContinueStmt(const clang::ContinueStmt &s); mlir::LogicalResult emitDoStmt(const clang::DoStmt &s); diff --git a/clang/test/CIR/CodeGen/compound_assign.cpp b/clang/test/CIR/CodeGen/compound_assign.cpp new file mode 100644 index 0000000000000..c54eb9e626016 --- /dev/null +++ b/clang/test/CIR/CodeGen/compound_assign.cpp @@ -0,0 +1,87 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +int compound_assign(int b) { + int x = 1; + x *= b; + x /= b; + x %= b; + x += b; + x -= b; + x >>= b; + x <<= b; + x &= b; + x ^= b; + x |= b; + return x; +} + +// CIR: cir.func @_Z15compound_assigni +// CIR: %[[MUL:.*]] = cir.binop(mul, %{{.*}}, %{{.*}}) nsw : !s32i +// CIR: cir.store %[[MUL]], %{{.*}} : !s32i, !cir.ptr<!s32i> +// CIR: %[[DIV:.*]] = cir.binop(div, %{{.*}}, %{{.*}}) : !s32i +// CIR: cir.store %[[DIV]], %{{.*}} : !s32i, !cir.ptr<!s32i> +// CIR: %[[REM:.*]] = cir.binop(rem, %{{.*}}, %{{.*}}) : !s32i +// CIR: cir.store %[[REM]], %{{.*}} : !s32i, !cir.ptr<!s32i> +// CIR: %[[ADD:.*]] = cir.binop(add, %{{.*}}, %{{.*}}) nsw : !s32i +// CIR: cir.store %[[ADD]], %{{.*}} : !s32i, !cir.ptr<!s32i> +// CIR: %[[SUB:.*]] = cir.binop(sub, %{{.*}}, %{{.*}}) nsw : !s32i +// CIR: cir.store %[[SUB]], %{{.*}} : !s32i, !cir.ptr<!s32i> +// CIR: %[[SHR:.*]] = cir.shift(right, %{{.*}} : !s32i, %{{.*}} : !s32i) -> !s32i +// CIR: cir.store %[[SHR]], %{{.*}} : !s32i, !cir.ptr<!s32i> +// CIR: %[[SHL:.*]] = cir.shift(left, %{{.*}} : !s32i, %{{.*}} : !s32i) -> !s32i +// CIR: cir.store %[[SHL]], %{{.*}} : !s32i, !cir.ptr<!s32i> +// CIR: %[[AND:.*]] = cir.binop(and, %{{.*}}, %{{.*}}) : !s32i +// CIR: cir.store %[[AND]], %{{.*}} : !s32i, !cir.ptr<!s32i> +// CIR: %[[XOR:.*]] = cir.binop(xor, %{{.*}}, %{{.*}}) : !s32i +// CIR: cir.store %[[XOR]], %{{.*}} : !s32i, !cir.ptr<!s32i> +// CIR: %[[OR:.*]] = cir.binop(or, %{{.*}}, %{{.*}}) : !s32i +// CIR: cir.store %[[OR]], %{{.*}} : !s32i, !cir.ptr<!s32i> + +// LLVM: define {{.*}}i32 @_Z15compound_assigni +// LLVM: %[[MUL:.*]] = mul nsw i32 %{{.*}}, %{{.*}} +// LLVM: store i32 %[[MUL]], ptr %{{.*}} +// LLVM: %[[DIV:.*]] = sdiv i32 %{{.*}}, %{{.*}} +// LLVM: store i32 %[[DIV]], ptr %{{.*}} +// LLVM: %[[REM:.*]] = srem i32 %{{.*}}, %{{.*}} +// LLVM: store i32 %[[REM]], ptr %{{.*}} +// LLVM: %[[ADD:.*]] = add nsw i32 %{{.*}}, %{{.*}} +// LLVM: store i32 %[[ADD]], ptr %{{.*}} +// LLVM: %[[SUB:.*]] = sub nsw i32 %{{.*}}, %{{.*}} +// LLVM: store i32 %[[SUB]], ptr %{{.*}} +// LLVM: %[[SHR:.*]] = ashr i32 %{{.*}}, %{{.*}} +// LLVM: store i32 %[[SHR]], ptr %{{.*}} +// LLVM: %[[SHL:.*]] = shl i32 %{{.*}}, %{{.*}} +// LLVM: store i32 %[[SHL]], ptr %{{.*}} +// LLVM: %[[AND:.*]] = and i32 %{{.*}}, %{{.*}} +// LLVM: store i32 %[[AND]], ptr %{{.*}} +// LLVM: %[[XOR:.*]] = xor i32 %{{.*}}, %{{.*}} +// LLVM: store i32 %[[XOR]], ptr %{{.*}} +// LLVM: %[[OR:.*]] = or i32 %{{.*}}, %{{.*}} +// LLVM: store i32 %[[OR]], ptr %{{.*}} + +// OGCG: define {{.*}}i32 @_Z15compound_assigni +// OGCG: %[[MUL:.*]] = mul nsw i32 %{{.*}}, %{{.*}} +// OGCG: store i32 %[[MUL]], ptr %{{.*}} +// OGCG: %[[DIV:.*]] = sdiv i32 %{{.*}}, %{{.*}} +// OGCG: store i32 %[[DIV]], ptr %{{.*}} +// OGCG: %[[REM:.*]] = srem i32 %{{.*}}, %{{.*}} +// OGCG: store i32 %[[REM]], ptr %{{.*}} +// OGCG: %[[ADD:.*]] = add nsw i32 %{{.*}}, %{{.*}} +// OGCG: store i32 %[[ADD]], ptr %{{.*}} +// OGCG: %[[SUB:.*]] = sub nsw i32 %{{.*}}, %{{.*}} +// OGCG: store i32 %[[SUB]], ptr %{{.*}} +// OGCG: %[[SHR:.*]] = ashr i32 %{{.*}}, %{{.*}} +// OGCG: store i32 %[[SHR]], ptr %{{.*}} +// OGCG: %[[SHL:.*]] = shl i32 %{{.*}}, %{{.*}} +// OGCG: store i32 %[[SHL]], ptr %{{.*}} +// OGCG: %[[AND:.*]] = and i32 %{{.*}}, %{{.*}} +// OGCG: store i32 %[[AND]], ptr %{{.*}} +// OGCG: %[[XOR:.*]] = xor i32 %{{.*}}, %{{.*}} +// OGCG: store i32 %[[XOR]], ptr %{{.*}} +// OGCG: %[[OR:.*]] = or i32 %{{.*}}, %{{.*}} +// OGCG: store i32 %[[OR]], ptr %{{.*}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits