Skip to content

Commit 68ea944

Browse files
committed
[CIR][CodeGen] Add basic support for unary plus/minus
1 parent 4cc4c32 commit 68ea944

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,11 +334,46 @@ 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+
344+
// NOTE(cir): we build the unary operation here, further lowering
345+
// is performed by the LowerToLLVM passes.
346+
return buildUnaryOp(E, mlir::cir::UnaryOpKind::Plus, result);
347+
}
348+
349+
mlir::Value VisitPlus(const UnaryOperator *E, QualType PromotionType) {
350+
// This differs from gcc, though, most likely due to a bug in gcc.
351+
TestAndClearIgnoreResultAssign();
352+
if (!PromotionType.isNull())
353+
assert(0 && "scalar promotion not implemented yet");
354+
return Visit(E->getSubExpr());
338355
}
356+
339357
mlir::Value VisitUnaryMinus(const UnaryOperator *E) {
340-
llvm_unreachable("NYI");
358+
// NOTE(cir): QualType function parameter still not used, so don´t replicate
359+
// it here yet.
360+
QualType promotionTy = getPromotionType(E->getSubExpr()->getType());
361+
auto result = VisitMinus(E, promotionTy);
362+
if (result && !promotionTy.isNull())
363+
assert(0 && "not implemented yet");
364+
365+
// NOTE(cir): we build the unary operation here, further lowering
366+
// is performed by the LowerToLLVM passes.
367+
return buildUnaryOp(E, mlir::cir::UnaryOpKind::Minus, result);
341368
}
369+
370+
mlir::Value VisitMinus(const UnaryOperator *E, QualType PromotionType) {
371+
TestAndClearIgnoreResultAssign();
372+
if (!PromotionType.isNull())
373+
assert(0 && "scalar promotion not implemented yet");
374+
return Visit(E->getSubExpr());
375+
}
376+
342377
mlir::Value VisitUnaryNot(const UnaryOperator *E) { llvm_unreachable("NYI"); }
343378
mlir::Value VisitUnaryLNot(const UnaryOperator *E) {
344379
llvm_unreachable("NYI");
@@ -592,6 +627,21 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
592627
buildCompoundAssign(const CompoundAssignOperator *E,
593628
mlir::Value (ScalarExprEmitter::*F)(const BinOpInfo &));
594629

630+
QualType getPromotionType(QualType Ty) {
631+
if (CGF.getContext()
632+
.getTargetInfo()
633+
.shouldEmitFloat16WithExcessPrecision()) {
634+
if (Ty->isAnyComplexType()) {
635+
QualType ElementType = Ty->castAs<ComplexType>()->getElementType();
636+
if (ElementType->isFloat16Type())
637+
return CGF.getContext().getComplexType(CGF.getContext().FloatTy);
638+
}
639+
if (Ty->isFloat16Type())
640+
return CGF.getContext().FloatTy;
641+
}
642+
return QualType();
643+
}
644+
595645
// Binary operators and binary compound assignment operators.
596646
#define HANDLEBINOP(OP) \
597647
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)