Skip to content

Commit 7f314ab

Browse files
cmarcelobcardosolopes
authored andcommitted
[CIR][CodeGen] Add basic support for unary plus/minus
1 parent 8ddfad9 commit 7f314ab

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,11 +334,44 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
334334
llvm_unreachable("NYI");
335335
}
336336
mlir::Value VisitUnaryPlus(const UnaryOperator *E) {
337-
llvm_unreachable("NYI");
337+
// NOTE(cir): QualType function parameter still not used, so don´t replicate
338+
// it here yet.
339+
QualType promotionTy = getPromotionType(E->getSubExpr()->getType());
340+
auto result = VisitPlus(E, promotionTy);
341+
if (result && !promotionTy.isNull())
342+
assert(0 && "not implemented yet");
343+
return buildUnaryOp(E, mlir::cir::UnaryOpKind::Plus, result);
344+
}
345+
346+
mlir::Value VisitPlus(const UnaryOperator *E, QualType PromotionType) {
347+
// This differs from gcc, though, most likely due to a bug in gcc.
348+
TestAndClearIgnoreResultAssign();
349+
if (!PromotionType.isNull())
350+
assert(0 && "scalar promotion not implemented yet");
351+
return Visit(E->getSubExpr());
338352
}
353+
339354
mlir::Value VisitUnaryMinus(const UnaryOperator *E) {
340-
llvm_unreachable("NYI");
355+
// NOTE(cir): QualType function parameter still not used, so don´t replicate
356+
// it here yet.
357+
QualType promotionTy = getPromotionType(E->getSubExpr()->getType());
358+
auto result = VisitMinus(E, promotionTy);
359+
if (result && !promotionTy.isNull())
360+
assert(0 && "not implemented yet");
361+
return buildUnaryOp(E, mlir::cir::UnaryOpKind::Minus, result);
362+
}
363+
364+
mlir::Value VisitMinus(const UnaryOperator *E, QualType PromotionType) {
365+
TestAndClearIgnoreResultAssign();
366+
if (!PromotionType.isNull())
367+
assert(0 && "scalar promotion not implemented yet");
368+
369+
// NOTE: LLVM codegen will lower this directly to either a FNeg
370+
// or a Sub instruction. In CIR this will be handled later in LowerToLLVM.
371+
372+
return Visit(E->getSubExpr());
341373
}
374+
342375
mlir::Value VisitUnaryNot(const UnaryOperator *E) { llvm_unreachable("NYI"); }
343376
mlir::Value VisitUnaryLNot(const UnaryOperator *E) {
344377
llvm_unreachable("NYI");
@@ -592,6 +625,22 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
592625
buildCompoundAssign(const CompoundAssignOperator *E,
593626
mlir::Value (ScalarExprEmitter::*F)(const BinOpInfo &));
594627

628+
// TODO(cir): Candidate to be in a common AST helper between CIR and LLVM codegen.
629+
QualType getPromotionType(QualType Ty) {
630+
if (CGF.getContext()
631+
.getTargetInfo()
632+
.shouldEmitFloat16WithExcessPrecision()) {
633+
if (Ty->isAnyComplexType()) {
634+
QualType ElementType = Ty->castAs<ComplexType>()->getElementType();
635+
if (ElementType->isFloat16Type())
636+
return CGF.getContext().getComplexType(CGF.getContext().FloatTy);
637+
}
638+
if (Ty->isFloat16Type())
639+
return CGF.getContext().FloatTy;
640+
}
641+
return QualType();
642+
}
643+
595644
// Binary operators and binary compound assignment operators.
596645
#define HANDLEBINOP(OP) \
597646
mlir::Value VisitBin##OP(const BinaryOperator *E) { \

clang/test/CIR/CodeGen/unary.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-enable -Wno-unused-value -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s
3+
4+
unsigned up0() {
5+
unsigned a = 1;
6+
return +a;
7+
}
8+
9+
// CHECK: cir.func @_Z3up0v() -> i32 {
10+
// CHECK: %[[#RET:]] = cir.alloca i32, cir.ptr <i32>, ["__retval"]
11+
// CHECK: %[[#A:]] = cir.alloca i32, cir.ptr <i32>, ["a", init]
12+
// CHECK: %[[#INPUT:]] = cir.load %[[#A]]
13+
// CHECK: %[[#OUTPUT:]] = cir.unary(plus, %[[#INPUT]])
14+
// CHECK: cir.store %[[#OUTPUT]], %[[#RET]]
15+
16+
unsigned um0() {
17+
unsigned a = 1;
18+
return -a;
19+
}
20+
21+
// CHECK: cir.func @_Z3um0v() -> i32 {
22+
// CHECK: %[[#RET:]] = cir.alloca i32, cir.ptr <i32>, ["__retval"]
23+
// CHECK: %[[#A:]] = cir.alloca i32, cir.ptr <i32>, ["a", init]
24+
// CHECK: %[[#INPUT:]] = cir.load %[[#A]]
25+
// CHECK: %[[#OUTPUT:]] = cir.unary(minus, %[[#INPUT]])
26+
// CHECK: cir.store %[[#OUTPUT]], %[[#RET]]

0 commit comments

Comments
 (0)