Skip to content

Commit c603785

Browse files
committed
[CIR] Add Support For Library Builtins
This patch upstreams support for builtins that map to a standard library function. Examples would be abort() and printf(). It also fixes a minor issue with the errorNYI for all remaining unimplemented builtins using the mlir::Location instead of the clang AST SourceLocation.
1 parent 8a2895a commit c603785

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ struct MissingFeatures {
230230
static bool attributeNoBuiltin() { return false; }
231231
static bool thunks() { return false; }
232232
static bool runCleanupsScope() { return false; }
233+
static bool asmLabelAttr() { return false; }
233234

234235
// Missing types
235236
static bool dataMemberType() { return false; }

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,18 @@
2020
#include "mlir/Support/LLVM.h"
2121
#include "clang/AST/Expr.h"
2222
#include "clang/AST/GlobalDecl.h"
23+
#include "clang/CIR/MissingFeatures.h"
2324
#include "llvm/Support/ErrorHandling.h"
2425

2526
using namespace clang;
2627
using namespace clang::CIRGen;
28+
using namespace llvm;
29+
30+
static RValue emitLibraryCall(CIRGenFunction &cgf, const FunctionDecl *fd,
31+
const CallExpr *e, mlir::Operation *calleeValue) {
32+
CIRGenCallee callee = CIRGenCallee::forDirect(calleeValue, GlobalDecl(fd));
33+
return cgf.emitCall(e->getCallee()->getType(), callee, e, ReturnValueSlot());
34+
}
2735

2836
RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
2937
const CallExpr *e,
@@ -49,7 +57,34 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
4957
}
5058
}
5159

52-
mlir::Location loc = getLoc(e->getExprLoc());
53-
cgm.errorNYI(loc, "non constant foldable builtin calls");
60+
const FunctionDecl *fd = gd.getDecl()->getAsFunction();
61+
62+
// If this is an alias for a lib function (e.g. __builtin_sin), emit
63+
// the call using the normal call path, but using the unmangled
64+
// version of the function name.
65+
if (getContext().BuiltinInfo.isLibFunction(builtinID))
66+
return emitLibraryCall(*this, fd, e,
67+
cgm.getBuiltinLibFunction(fd, builtinID));
68+
69+
cgm.errorNYI(e->getSourceRange(), "non constant foldable builtin calls");
5470
return getUndefRValue(e->getType());
5571
}
72+
73+
/// Given a builtin id for a function like "__builtin_fabsf", return a Function*
74+
/// for "fabsf".
75+
cir::FuncOp CIRGenModule::getBuiltinLibFunction(const FunctionDecl *fd,
76+
unsigned builtinID) {
77+
assert(astContext.BuiltinInfo.isLibFunction(builtinID));
78+
79+
// Get the name, skip over the __builtin_ prefix (if necessary). We may have
80+
// to build this up so provide a small stack buffer to handle the vast
81+
// majority of names.
82+
llvm::SmallString<64> name;
83+
84+
assert(!cir::MissingFeatures::asmLabelAttr());
85+
name = astContext.BuiltinInfo.getName(builtinID).substr(10);
86+
87+
GlobalDecl d(fd);
88+
mlir::Type type = convertType(fd->getType());
89+
return getOrCreateCIRFunction(name, type, d, /*forVTable=*/false);
90+
}

clang/lib/CIR/CodeGen/CIRGenModule.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ class CIRGenModule : public CIRGenTypeCache {
288288
cir::FuncType funcType,
289289
const clang::FunctionDecl *funcDecl);
290290

291+
/// Given a builtin id for a function like "__builtin_fabsf", return a
292+
/// Function* for "fabsf".
293+
cir::FuncOp getBuiltinLibFunction(const FunctionDecl *fd, unsigned builtinID);
294+
291295
mlir::IntegerAttr getSize(CharUnits size) {
292296
return builder.getSizeFromCharUnits(size);
293297
}

clang/test/CIR/CodeGen/builtin_call.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,21 @@ float constant_fp_builtin_single() {
7676
// OGCG: define {{.*}}float @_Z26constant_fp_builtin_singlev()
7777
// OGCG: ret float 0x3FB99999A0000000
7878
// OGCG: }
79+
80+
void library_builtins() {
81+
__builtin_printf(nullptr);
82+
__builtin_abort();
83+
}
84+
85+
// CIR: cir.func @_Z16library_builtinsv() {
86+
// CIR: %[[NULL:.+]] = cir.const #cir.ptr<null> : !cir.ptr<!s8i>
87+
// CIR: cir.call @printf(%[[NULL]]) : (!cir.ptr<!s8i>) -> !s32i
88+
// CIR: cir.call @abort() : () -> ()
89+
90+
// LLVM: define void @_Z16library_builtinsv()
91+
// LLVM: call i32 (ptr, ...) @printf(ptr null)
92+
// LLVM: call void @abort()
93+
94+
// OGCG: define dso_local void @_Z16library_builtinsv()
95+
// OGCG: call i32 (ptr, ...) @printf(ptr noundef null)
96+
// OGCG: call void @abort()

0 commit comments

Comments
 (0)