diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index e3ddbe75df81..df7cc6bce6df 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -27,12 +27,20 @@ #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/IR/Value.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "llvm/Support/ErrorHandling.h" using namespace cir; using namespace clang; using namespace mlir::cir; using namespace llvm; +static RValue buildLibraryCall(CIRGenFunction &CGF, const FunctionDecl *FD, + const CallExpr *E, + mlir::Operation *calleeValue) { + auto callee = CIRGenCallee::forDirect(calleeValue, GlobalDecl(FD)); + return CGF.buildCall(E->getCallee()->getType(), callee, E, ReturnValueSlot()); +} + RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue) { @@ -334,6 +342,13 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, llvm_unreachable("NYI"); break; + case Builtin::BIprintf: + if (getTarget().getTriple().isNVPTX() || + getTarget().getTriple().isAMDGCN()) { + llvm_unreachable("NYI"); + } + break; + // C++ std:: builtins. case Builtin::BImove: case Builtin::BImove_if_noexcept: @@ -387,7 +402,8 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // If this is a predefined lib function (e.g. malloc), emit the call // using exactly the normal call path. if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) - llvm_unreachable("NYI"); + return buildLibraryCall(*this, FD, E, + buildScalarExpr(E->getCallee()).getDefiningOp()); // Check that a call to a target specific builtin has the correct target // features. diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index e3f9801f5222..39190f3fe304 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -19,12 +19,15 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/GlobalDecl.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" +#include #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/BuiltinTypes.h" +#include "mlir/IR/SymbolTable.h" #include "mlir/IR/Types.h" using namespace cir; @@ -503,6 +506,16 @@ RValue CIRGenFunction::buildCall(const CIRGenFunctionInfo &CallInfo, } else if (auto loadOp = dyn_cast(CalleePtr)) { theCall = builder.create(callLoc, loadOp->getResult(0), CIRFuncTy, CIRCallArgs); + } else if (auto getGlobalOp = dyn_cast(CalleePtr)) { + // FIXME(cir): This peephole optimization to avoids indirect calls for + // builtins. This should be fixed in the builting declaration instead by not + // emitting an unecessary get_global in the first place. + auto *globalOp = mlir::SymbolTable::lookupSymbolIn(CGM.getModule(), + getGlobalOp.getName()); + assert(getGlobalOp && "undefined global function"); + auto callee = llvm::dyn_cast(globalOp); + assert(callee && "operation is not a function"); + theCall = builder.create(callLoc, callee, CIRCallArgs); } else { llvm_unreachable("expected call variant to be handled"); } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 4640eac3eef6..9cb7bb0f6c68 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -604,6 +604,13 @@ class CIRGetGlobalOpLowering mlir::LogicalResult matchAndRewrite(mlir::cir::GetGlobalOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const override { + // FIXME(cir): Premature DCE to avoid lowering stuff we're not using. CIRGen + // should mitigate this and not emit the get_global. + if (op->getUses().empty()) { + rewriter.eraseOp(op); + return mlir::success(); + } + auto type = getTypeConverter()->convertType(op.getType()); auto symbol = op.getName(); rewriter.replaceOpWithNewOp(op, type, symbol); diff --git a/clang/test/CIR/Executables/hello.c b/clang/test/CIR/Executables/hello.c index 02c11eec997e..c3705fe0210b 100644 --- a/clang/test/CIR/Executables/hello.c +++ b/clang/test/CIR/Executables/hello.c @@ -2,7 +2,7 @@ // RUN: %t | FileCheck %s // REQUIRES: system-linux // REQUIRES: target-linux -int printf(const char *format); +int printf(const char *restrict, ...); int main (void) { printf ("Hello, world!\n");