[clang] [CIR] Support void calls in cir.call_llvm_intrinsic lowering (PR #199516)
via cfe-commits
cfe-commits at lists.llvm.org
Mon May 25 10:09:05 PDT 2026
https://github.com/skc7 updated https://github.com/llvm/llvm-project/pull/199516
>From 4f96d7b0eb8f0ef4578a7718e99a7c91a7c67f55 Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Mon, 25 May 2026 15:08:32 +0530
Subject: [PATCH] [CIR] Fix cir.call_llvm_intrinsic lowering for 0-result ops
---
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 20 +++++++++-----
.../test/CIR/Lowering/call-llvm-intrinsic.cir | 27 +++++++++++++++++++
2 files changed, 41 insertions(+), 6 deletions(-)
create mode 100644 clang/test/CIR/Lowering/call-llvm-intrinsic.cir
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index c4e98e299dfc1..8940272d27ffe 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -358,8 +358,12 @@ createCallLLVMIntrinsicOp(mlir::ConversionPatternRewriter &rewriter,
mlir::Type resultTy, mlir::ValueRange operands) {
auto intrinsicNameAttr =
mlir::StringAttr::get(rewriter.getContext(), intrinsicName);
- return mlir::LLVM::CallIntrinsicOp::create(rewriter, loc, resultTy,
- intrinsicNameAttr, operands);
+ // CallIntrinsicOp has distinct void / single-result create overloads.
+ if (resultTy)
+ return mlir::LLVM::CallIntrinsicOp::create(rewriter, loc, resultTy,
+ intrinsicNameAttr, operands);
+ return mlir::LLVM::CallIntrinsicOp::create(rewriter, loc, intrinsicNameAttr,
+ operands);
}
static mlir::LLVM::CallIntrinsicOp replaceOpWithCallLLVMIntrinsicOp(
@@ -375,10 +379,14 @@ static mlir::LLVM::CallIntrinsicOp replaceOpWithCallLLVMIntrinsicOp(
mlir::LogicalResult CIRToLLVMLLVMIntrinsicCallOpLowering::matchAndRewrite(
cir::LLVMIntrinsicCallOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type llvmResTy =
- getTypeConverter()->convertType(op->getResultTypes()[0]);
- if (!llvmResTy)
- return op.emitError("expected LLVM result type");
+ // Result is Optional on the op, so void intrinsics have zero
+ // results; leave llvmResTy null in that case.
+ mlir::Type llvmResTy;
+ if (op->getNumResults() != 0) {
+ llvmResTy = getTypeConverter()->convertType(op->getResultTypes()[0]);
+ if (!llvmResTy)
+ return op.emitError("expected LLVM result type");
+ }
StringRef name = op.getIntrinsicName();
// Some LLVM intrinsics require ElementType attribute to be attached to
diff --git a/clang/test/CIR/Lowering/call-llvm-intrinsic.cir b/clang/test/CIR/Lowering/call-llvm-intrinsic.cir
new file mode 100644
index 0000000000000..edd492aa7477c
--- /dev/null
+++ b/clang/test/CIR/Lowering/call-llvm-intrinsic.cir
@@ -0,0 +1,27 @@
+// RUN: cir-opt %s -cir-to-llvm -o - | FileCheck %s
+
+// Contract test for CIRToLLVMLLVMIntrinsicCallOpLowering: the op def
+// declares Optional<CIR_AnyType>:$result, so the lowering must accept
+// 0-result (void) calls in addition to the single-result case.
+
+!s32i = !cir.int<s, 32>
+
+module {
+ // 0-result, 0-operand.
+ // CHECK-LABEL: llvm.func @void_no_operands
+ // CHECK: llvm.call_intrinsic "llvm.donothing"() : () -> ()
+ // CHECK: llvm.return
+ cir.func @void_no_operands() {
+ cir.call_llvm_intrinsic "donothing" : () -> ()
+ cir.return
+ }
+
+ // 0-result with one operand.
+ // CHECK-LABEL: llvm.func @void_with_operand
+ // CHECK: llvm.call_intrinsic "llvm.amdgcn.s.sleep"(%{{.*}}) : (i32) -> ()
+ // CHECK: llvm.return
+ cir.func @void_with_operand(%arg0: !s32i) {
+ cir.call_llvm_intrinsic "amdgcn.s.sleep" %arg0 : (!s32i) -> ()
+ cir.return
+ }
+}
More information about the cfe-commits
mailing list