mirror of
https://github.com/intel/llvm.git
synced 2026-01-17 14:48:27 +08:00
[CIR] Upstream var arg copy builtin (#169415)
This PR upstreams `__builtin_va_copy`, and extends the existing tests.
This commit is contained in:
@@ -4820,6 +4820,37 @@ def CIR_VAEndOp : CIR_Op<"va_end"> {
|
||||
}];
|
||||
}
|
||||
|
||||
def CIR_VACopyOp : CIR_Op<"va_copy"> {
|
||||
let summary = "Copied a variable argument list";
|
||||
let description = [{
|
||||
The `cir.copy` operation models the C/C++ va_copy macro.
|
||||
The variable argument list passed as the `$src_list` is copied to an
|
||||
unitialized `va_list` in the destination operand. The next argument that
|
||||
can be extracted from the copied list is the same as the next argument in
|
||||
the source list. The copied list must be destroyed with `va_end`.
|
||||
|
||||
Example:
|
||||
|
||||
```mlir
|
||||
// %args : !cir.ptr<!cir.array<!rec___va_list_tag x 1>>
|
||||
%p = cir.cast array_to_ptrdecay %args
|
||||
: !cir.ptr<!cir.array<!rec___va_list_tag x 1>>
|
||||
-> !cir.ptr<!rec___va_list_tag>
|
||||
cir.va_copy %p to %dst
|
||||
: (!cir.ptr<!rec___va_list_tag>, !cir.ptr<!rec___va_list_tag>)
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins
|
||||
CIR_PointerType:$dst_list,
|
||||
CIR_PointerType:$src_list
|
||||
);
|
||||
|
||||
let assemblyFormat = [{
|
||||
$src_list `to` $dst_list attr-dict `:` type(operands)
|
||||
}];
|
||||
}
|
||||
|
||||
def CIR_VAArgOp : CIR_Op<"va_arg"> {
|
||||
let summary = "Fetches next variadic element as a given type";
|
||||
let description = [{
|
||||
|
||||
@@ -266,7 +266,12 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
|
||||
case Builtin::BI__builtin_va_end:
|
||||
emitVAEnd(emitVAListRef(e->getArg(0)).getPointer());
|
||||
return {};
|
||||
|
||||
case Builtin::BI__builtin_va_copy: {
|
||||
mlir::Value dstPtr = emitVAListRef(e->getArg(0)).getPointer();
|
||||
mlir::Value srcPtr = emitVAListRef(e->getArg(1)).getPointer();
|
||||
cir::VACopyOp::create(builder, dstPtr.getLoc(), dstPtr, srcPtr);
|
||||
return {};
|
||||
}
|
||||
case Builtin::BIcos:
|
||||
case Builtin::BIcosf:
|
||||
case Builtin::BIcosl:
|
||||
|
||||
@@ -4061,6 +4061,18 @@ mlir::LogicalResult CIRToLLVMVAEndOpLowering::matchAndRewrite(
|
||||
return mlir::success();
|
||||
}
|
||||
|
||||
mlir::LogicalResult CIRToLLVMVACopyOpLowering::matchAndRewrite(
|
||||
cir::VACopyOp op, OpAdaptor adaptor,
|
||||
mlir::ConversionPatternRewriter &rewriter) const {
|
||||
auto opaquePtr = mlir::LLVM::LLVMPointerType::get(getContext());
|
||||
auto dstList = mlir::LLVM::BitcastOp::create(rewriter, op.getLoc(), opaquePtr,
|
||||
adaptor.getDstList());
|
||||
auto srcList = mlir::LLVM::BitcastOp::create(rewriter, op.getLoc(), opaquePtr,
|
||||
adaptor.getSrcList());
|
||||
rewriter.replaceOpWithNewOp<mlir::LLVM::VaCopyOp>(op, dstList, srcList);
|
||||
return mlir::success();
|
||||
}
|
||||
|
||||
mlir::LogicalResult CIRToLLVMVAArgOpLowering::matchAndRewrite(
|
||||
cir::VAArgOp op, OpAdaptor adaptor,
|
||||
mlir::ConversionPatternRewriter &rewriter) const {
|
||||
|
||||
@@ -141,7 +141,7 @@ int stdarg_start(int count, ...) {
|
||||
// OGCG: %[[COND:.+]] = icmp ule i32 %[[GPOFFSET]], 40
|
||||
// OGCG: br i1 %[[COND]], label %vaarg.in_reg, label %vaarg.in_mem
|
||||
//
|
||||
// OGCG: vaarg.in_reg:
|
||||
// OGCG: vaarg.in_reg:
|
||||
// OGCG: %[[REGSAVE_PTR:.+]] = getelementptr inbounds nuw %struct.__va_list_tag, ptr %[[DECAY1]], i32 0, i32 3
|
||||
// OGCG: %[[REGSAVE:.+]] = load ptr, ptr %[[REGSAVE_PTR]]
|
||||
// OGCG: %[[VAADDR1:.+]] = getelementptr i8, ptr %[[REGSAVE]], i32 %[[GPOFFSET]]
|
||||
@@ -164,3 +164,23 @@ int stdarg_start(int count, ...) {
|
||||
// OGCG: call void @llvm.va_end.p0(ptr %[[DECAY2]])
|
||||
// OGCG: %[[VAL:.+]] = load i32, ptr %[[RES_ADDR]]
|
||||
// OGCG: ret i32 %[[VAL]]
|
||||
|
||||
void stdarg_copy() {
|
||||
__builtin_va_list src, dest;
|
||||
__builtin_va_copy(src, dest);
|
||||
}
|
||||
|
||||
// CIR-LABEL: @stdarg_copy
|
||||
// CIR: %{{.*}} = cir.cast array_to_ptrdecay %{{.*}} : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag>
|
||||
// CIR: %{{.*}} = cir.cast array_to_ptrdecay %{{.*}} : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag>
|
||||
// CIR: cir.va_copy %{{.*}} to %{{.*}} : !cir.ptr<!rec___va_list_tag>, !cir.ptr<!rec___va_list_tag>
|
||||
|
||||
// LLVM-LABEL: @stdarg_copy
|
||||
// LLVM: %{{.*}} = getelementptr %struct.__va_list_tag, ptr %{{.*}}
|
||||
// LLVM: %{{.*}} = getelementptr %struct.__va_list_tag, ptr %{{.*}}
|
||||
// LLVM: call void @llvm.va_copy.p0(ptr %{{.*}}, ptr %{{.*}}
|
||||
|
||||
// OGCG-LABEL: @stdarg_copy
|
||||
// OGCG: %{{.*}} = getelementptr inbounds [1 x %struct.__va_list_tag], ptr %{{.*}}
|
||||
// OGCG: %{{.*}} = getelementptr inbounds [1 x %struct.__va_list_tag], ptr %{{.*}}
|
||||
// OGCG: call void @llvm.va_copy.p0(ptr %{{.*}}, ptr %{{.*}}
|
||||
|
||||
Reference in New Issue
Block a user