Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,10 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
return getConstantInt(loc, getUInt32Ty(), c);
}
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc) {
cir::IntType sInt64Ty = getSInt64Ty();
return cir::ConstantOp::create(*this, loc, cir::IntAttr::get(sInt64Ty, c));
return getConstantInt(loc, getSInt64Ty(), c);
}
cir::ConstantOp getUInt64(uint64_t c, mlir::Location loc) {
return getConstantInt(loc, getUInt64Ty(), c);
}

mlir::Value createNeg(mlir::Value value) {
Expand Down
16 changes: 16 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,22 @@ CIRGenFunction::emitTargetBuiltinExpr(unsigned builtinID, const CallExpr *e,
getTarget().getTriple().getArch());
}

mlir::Value CIRGenFunction::emitScalarOrConstFoldImmArg(
const unsigned iceArguments, const unsigned idx, const Expr *argExpr) {
mlir::Value arg = {};
if ((iceArguments & (1 << idx)) == 0) {
arg = emitScalarExpr(argExpr);
} else {
// If this is required to be a constant, constant fold it so that we
// know that the generated intrinsic gets a ConstantInt.
const std::optional<llvm::APSInt> result =
argExpr->getIntegerConstantExpr(getContext());
assert(result && "Expected argument to be a constant");
arg = builder.getConstInt(getLoc(argExpr->getSourceRange()), *result);
}
return arg;
}

/// Given a builtin id for a function like "__builtin_fabsf", return a Function*
/// for "fabsf".
cir::FuncOp CIRGenModule::getBuiltinLibFunction(const FunctionDecl *fd,
Expand Down
25 changes: 21 additions & 4 deletions clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "clang/Basic/Builtins.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/CIR/MissingFeatures.h"
#include "llvm/IR/IntrinsicsX86.h"

using namespace clang;
using namespace clang::CIRGen;
Expand Down Expand Up @@ -66,9 +65,8 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
getContext().GetBuiltinType(builtinID, error, &iceArguments);
assert(error == ASTContext::GE_None && "Error while getting builtin type.");

for (auto [idx, arg] : llvm::enumerate(e->arguments())) {
for (auto [idx, arg] : llvm::enumerate(e->arguments()))
ops.push_back(emitScalarOrConstFoldImmArg(iceArguments, idx, arg));
}

CIRGenBuilderTy &builder = getBuilder();
mlir::Type voidTy = builder.getVoidTy();
Expand Down Expand Up @@ -98,6 +96,10 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
case X86::BI__builtin_ia32_undef128:
case X86::BI__builtin_ia32_undef256:
case X86::BI__builtin_ia32_undef512:
cgm.errorNYI(e->getSourceRange(),
std::string("unimplemented X86 builtin call: ") +
getContext().BuiltinInfo.getName(builtinID));
return {};
case X86::BI__builtin_ia32_vec_ext_v4hi:
case X86::BI__builtin_ia32_vec_ext_v16qi:
case X86::BI__builtin_ia32_vec_ext_v8hi:
Expand All @@ -107,7 +109,22 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
case X86::BI__builtin_ia32_vec_ext_v32qi:
case X86::BI__builtin_ia32_vec_ext_v16hi:
case X86::BI__builtin_ia32_vec_ext_v8si:
case X86::BI__builtin_ia32_vec_ext_v4di:
case X86::BI__builtin_ia32_vec_ext_v4di: {
unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getSize();

uint64_t index =
ops[1].getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue();

index &= numElts - 1;

cir::ConstantOp indexVal =
builder.getUInt64(index, getLoc(e->getExprLoc()));

// These builtins exist so we can ensure the index is an ICE and in range.
// Otherwise we could just do this in the header file.
return cir::VecExtractOp::create(builder, getLoc(e->getExprLoc()), ops[0],
indexVal);
}
case X86::BI__builtin_ia32_vec_set_v4hi:
case X86::BI__builtin_ia32_vec_set_v16qi:
case X86::BI__builtin_ia32_vec_set_v8hi:
Expand Down
22 changes: 0 additions & 22 deletions clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1442,28 +1442,6 @@ mlir::Value CIRGenFunction::emitPromotedScalarExpr(const Expr *e,
return ScalarExprEmitter(*this, builder).Visit(const_cast<Expr *>(e));
}

mlir::Value CIRGenFunction::emitScalarOrConstFoldImmArg(unsigned iceArguments,
unsigned index,
const Expr *arg) {
mlir::Value result{};

// The bit at the specified index indicates whether the argument is required
// to be a constant integer expression.
bool isArgRequiredToBeConstant = (iceArguments & (1 << index));

if (!isArgRequiredToBeConstant) {
result = emitScalarExpr(arg);
} else {
// If this is required to be a constant, constant fold it so that we
// know that the generated intrinsic gets a ConstantInt.
std::optional<llvm::APSInt> iceOpt =
arg->getIntegerConstantExpr(getContext());
assert(iceOpt && "Expected argument to be a constant");
result = builder.getConstInt(getLoc(arg->getSourceRange()), *iceOpt);
}
return result;
}

[[maybe_unused]] static bool mustVisitNullValue(const Expr *e) {
// If a null pointer expression's type is the C++0x nullptr_t and
// the expression is not a simple literal, it must be evaluated
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/CIR/CodeGen/CIRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1546,9 +1546,6 @@ class CIRGenFunction : public CIRGenTypeCache {
mlir::Value emitScalarExpr(const clang::Expr *e,
bool ignoreResultAssign = false);

mlir::Value emitScalarOrConstFoldImmArg(unsigned iceArguments, unsigned index,
const Expr *arg);

mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv,
cir::UnaryOpKind kind, bool isPre);

Expand Down Expand Up @@ -1721,6 +1718,9 @@ class CIRGenFunction : public CIRGenTypeCache {
void emitScalarInit(const clang::Expr *init, mlir::Location loc,
LValue lvalue, bool capturedByInit = false);

mlir::Value emitScalarOrConstFoldImmArg(unsigned iceArguments, unsigned idx,
const Expr *argExpr);

void emitStaticVarDecl(const VarDecl &d, cir::GlobalLinkageKind linkage);

void emitStoreOfComplex(mlir::Location loc, mlir::Value v, LValue dest,
Expand Down
15 changes: 15 additions & 0 deletions clang/test/CIR/CodeGen/X86/sse2-builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@

#include <immintrin.h>

// Lowering to pextrw requires optimization.
int test_mm_extract_epi16(__m128i A) {
// CIR-LABEL: test_mm_extract_epi16
// CIR %{{.*}} = cir.vec.extract %{{.*}}[%{{.*}} : {{!u32i|!u64i}}] : !cir.vector<!s16i x 8>
// CIR %{{.*}} = cir.cast integral %{{.*}} : !u16i -> !s32i

// LLVM-LABEL: test_mm_extract_epi16
// LLVM: extractelement <8 x i16> %{{.*}}, {{i32|i64}} 1
// LLVM: zext i16 %{{.*}} to i32

// OGCG-LABEL: test_mm_extract_epi16
// OGCG: extractelement <8 x i16> %{{.*}}, {{i32|i64}} 1
// OGCG: zext i16 %{{.*}} to i32
return _mm_extract_epi16(A, 1);
}

void test_mm_clflush(void* A) {
// CIR-LABEL: test_mm_clflush
Expand Down
Loading