From 8f25523cd4f0330e0f45a997ec940a05ca8468b6 Mon Sep 17 00:00:00 2001 From: Kirill Yansitov <36601354+YazZz1k@users.noreply.github.com> Date: Thu, 8 Feb 2024 23:08:10 +0300 Subject: [PATCH] [CIR][CIRGen][Bugfix] Emit valid type for evaluated const (#456) This PR fixes the issue connected with folding a simple boolean expresion pattern (f.e. `0 && RHS = 0`). The problem is that the scalar expression emitter always creates a `cir.bool` attribute as a result of expression. But in some cases the result expression should be a `cir.int` attr. --- clang/lib/CIR/CodeGen/CIRGenBuilder.h | 11 +---------- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 10 +++++++--- clang/test/CIR/CodeGen/evaluate-expr.c | 20 ++++++++++++++++++++ 3 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 clang/test/CIR/CodeGen/evaluate-expr.c diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 35d6bcf5b5d1..19b01c5405b2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -552,16 +552,7 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy { // Creates constant null value for integral type ty. mlir::cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc) { - if (ty.isa()) - return getNullPtr(ty, loc); - - mlir::TypedAttr attr; - if (ty.isa()) - attr = mlir::cir::IntAttr::get(ty, 0); - else - llvm_unreachable("NYI"); - - return create(loc, ty, attr); + return create(loc, ty, getZeroInitAttr(ty)); } mlir::cir::ConstantOp getZero(mlir::Location loc, mlir::Type ty) { diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 96c5da4f2c82..de18fa610970 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -2147,7 +2147,7 @@ mlir::Value ScalarExprEmitter::VisitBinLAnd(const clang::BinaryOperator *E) { } // 0 && RHS: If it is safe, just elide the RHS, and return 0/false. if (!CGF.ContainsLabel(E->getRHS())) - return Builder.getBool(false, Loc); + return Builder.getNullValue(ResTy, Loc); } CIRGenFunction::ConditionalEvaluation eval(CGF); @@ -2220,8 +2220,12 @@ mlir::Value ScalarExprEmitter::VisitBinLOr(const clang::BinaryOperator *E) { return Builder.createZExtOrBitCast(RHSCond.getLoc(), RHSCond, ResTy); } // 1 || RHS: If it is safe, just elide the RHS, and return 1/true. - if (!CGF.ContainsLabel(E->getRHS())) - return Builder.getBool(true, Loc); + if (!CGF.ContainsLabel(E->getRHS())) { + if (auto intTy = ResTy.dyn_cast()) + return Builder.getConstInt(Loc, intTy, 1); + else + return Builder.getBool(true, Loc); + } } CIRGenFunction::ConditionalEvaluation eval(CGF); diff --git a/clang/test/CIR/CodeGen/evaluate-expr.c b/clang/test/CIR/CodeGen/evaluate-expr.c new file mode 100644 index 000000000000..d468bf1340db --- /dev/null +++ b/clang/test/CIR/CodeGen/evaluate-expr.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-enable -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s + +static const int g = 1; +void foo() { + if ((g != 1) && (g != 1)) + return; + if ((g == 1) || (g == 1)) + return; +} +// CHECK: cir.func no_proto @foo() +// CHECK: cir.scope { +// CHECK: [[ZERO:%.*]] = cir.const(#cir.int<0> : !s32i) : !s32i +// CHECK: [[FALSE:%.*]] = cir.cast(int_to_bool, [[ZERO:%.*]] : !s32i), !cir.bool +// CHECK: cir.if [[FALSE]] { +// CHECK: cir.return +// CHECK: } +// CHECK: } +// CHECK: cir.return +