Skip to content

Commit e78ac80

Browse files
authored
[CIR] Implement VAArgExpr for ComplexType (#156092)
This change adds support VAArgExpr for ComplexExpr Issue: #141365
1 parent 5a33bc5 commit e78ac80

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
182182
mlir::Value VisitBinDivAssign(const CompoundAssignOperator *e) {
183183
return emitCompoundAssign(e, &ComplexExprEmitter::emitBinDiv);
184184
}
185+
186+
mlir::Value VisitVAArgExpr(VAArgExpr *e);
185187
};
186188
} // namespace
187189

@@ -597,6 +599,10 @@ mlir::Value ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *e) {
597599
return builder.createNot(op);
598600
}
599601

602+
mlir::Value ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *e) {
603+
return cgf.emitVAArg(e);
604+
}
605+
600606
mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e,
601607
QualType promotionTy) {
602608
e = e->IgnoreParens();

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,3 +853,59 @@ void foo32() {
853853
// OGCG: %[[REAL_ADDR:.*]] = alloca i32, align 4
854854
// OGCG: %[[REAL:.*]] = load i32, ptr @_ZN9Container1cE, align 4
855855
// OGCG: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4
856+
857+
void foo33(__builtin_va_list a) {
858+
float _Complex b = __builtin_va_arg(a, float _Complex);
859+
}
860+
861+
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.ptr<!rec___va_list_tag>, !cir.ptr<!cir.ptr<!rec___va_list_tag>>, ["a", init]
862+
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init]
863+
// CIR: cir.store %[[ARG_0:.*]], %[[A_ADDR]] : !cir.ptr<!rec___va_list_tag>, !cir.ptr<!cir.ptr<!rec___va_list_tag>>
864+
// CIR: %[[VA_TAG:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.ptr<!rec___va_list_tag>>, !cir.ptr<!rec___va_list_tag>
865+
// CIR: %[[COMPLEX:.*]] = cir.va_arg %[[VA_TAG]] : (!cir.ptr<!rec___va_list_tag>) -> !cir.complex<!cir.float>
866+
// CIR: cir.store{{.*}} %[[COMPLEX]], %[[B_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
867+
868+
// LLVM: %[[A_ADDR:.*]] = alloca ptr, i64 1, align 8
869+
// LLVM: %[[B_ADDR:.*]] = alloca { float, float }, i64 1, align 4
870+
// LLVM: store ptr %[[ARG_0:.*]], ptr %[[A_ADDR]], align 8
871+
// LLVM: %[[TMP_A:.*]] = load ptr, ptr %[[A_ADDR]], align 8
872+
// LLVM: %[[COMPLEX:.*]] = va_arg ptr %[[TMP_A]], { float, float }
873+
// LLVM: store { float, float } %[[COMPLEX]], ptr %[[B_ADDR]], align 4
874+
875+
// TODO(CIR): the difference between the CIR LLVM and OGCG is because the lack of calling convention lowering,
876+
// Test will be updated when that is implemented
877+
878+
// OGCG: %[[A_ADDR:.*]] = alloca ptr, align 8
879+
// OGCG: %[[B_ADDR:.*]] = alloca { float, float }, align 4
880+
// OGCG: store ptr %[[ARG_0:.*]], ptr %[[A_ADDR]], align 8
881+
// OGCG: %[[TMP_A:.*]] = load ptr, ptr %[[A_ADDR]], align 8
882+
// OGCG: %[[GP_OFFSET_PTR:.*]] = getelementptr inbounds nuw %struct.__va_list_tag, ptr %[[TMP_A]], i32 0, i32 1
883+
// OGCG: %[[GP_OFFSET:.*]] = load i32, ptr %[[GP_OFFSET_PTR]], align 4
884+
// OGCG: %[[COND:.*]] = icmp ule i32 %[[GP_OFFSET]], 160
885+
// OGCG: br i1 %[[COND]], label %[[VA_ARG_IN_REG:.*]], label %[[VA_ARG_IN_MEM:.*]]
886+
//
887+
// OGCG: [[VA_ARG_IN_REG]]:
888+
// OGCG: %[[REG_SAVE_PTR:.*]] = getelementptr inbounds nuw %struct.__va_list_tag, ptr %[[TMP_A]], i32 0, i32 3
889+
// OGCG: %[[REG_SAVE:.*]] = load ptr, ptr %[[REG_SAVE_PTR]], align 8
890+
// OGCG: %[[VA_ADDR:..*]] = getelementptr i8, ptr %[[REG_SAVE]], i32 %[[GP_OFFSET]]
891+
// OGCG: %[[GP_OFFSET_NEXT:.*]] = add i32 %[[GP_OFFSET]], 16
892+
// OGCG: store i32 %[[GP_OFFSET_NEXT]], ptr %[[GP_OFFSET_PTR]], align 4
893+
// OGCG: br label %[[VA_ARG_END:.*]]
894+
//
895+
// OGCG: [[VA_ARG_IN_MEM]]:
896+
// OGCG: %[[OVERFLOW_PTR:.*]] = getelementptr inbounds nuw %struct.__va_list_tag, ptr %[[TMP_A]], i32 0, i32 2
897+
// OGCG: %[[OVERFLOW:.*]] = load ptr, ptr %[[OVERFLOW_PTR]], align 8
898+
// OGCG: %[[OVERFLOW_NEXT:.*]] = getelementptr i8, ptr %[[OVERFLOW]], i32 8
899+
// OGCG: store ptr %[[OVERFLOW_NEXT]], ptr %[[OVERFLOW_PTR]], align 8
900+
// OGCG: br label %[[VA_ARG_END]]
901+
//
902+
// OGCG: [[VA_ARG_END]]:
903+
// OGCG: %[[RESULT:.*]] = phi ptr [ %[[VA_ADDR]], %[[VA_ARG_IN_REG]] ], [ %[[OVERFLOW]], %[[VA_ARG_IN_MEM]] ]
904+
// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 0
905+
// OGCG: %[[RESULT_REAL:.*]] = load float, ptr %[[RESULT_REAL_PTR]], align 4
906+
// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 1
907+
// OGCG: %[[RESULT_IMAG:.*]] = load float, ptr %[[RESULT_IMAG_PTR]], align 4
908+
// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 0
909+
// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 1
910+
// OGCG: store float %[[RESULT_REAL]], ptr %[[B_REAL_PTR]], align 4
911+
// OGCG: store float %[[RESULT_IMAG]], ptr %[[B_IMAG_PTR]], align 4

0 commit comments

Comments
 (0)