From d329c96a56b41ad99ddffe7bd037ac4ab7476ce6 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Tue, 28 Jan 2025 19:55:20 -0800 Subject: [PATCH] [CIR] Fix vector issues from latest rebase --- clang/lib/CIR/CodeGen/ABIInfo.h | 9 ++ clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 92 +++++++++---------- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 4 + clang/lib/CIR/CodeGen/CIRGenModule.h | 2 +- clang/lib/CIR/CodeGen/TargetInfo.cpp | 9 ++ .../Transforms/TargetLowering/ABIInfo.h | 1 + clang/test/CIR/CodeGen/OpenCL/printf.cl | 1 - clang/test/CIR/CodeGen/builtins-elementwise.c | 1 - clang/test/CIR/CodeGen/vectype.cpp | 1 - .../test/CIR/Lowering/ThroughMLIR/vectype.cpp | 1 - clang/test/CIR/Lowering/vectype.cpp | 1 - 11 files changed, 67 insertions(+), 55 deletions(-) diff --git a/clang/lib/CIR/CodeGen/ABIInfo.h b/clang/lib/CIR/CodeGen/ABIInfo.h index 6ac37bb01350..cb8dabb31df6 100644 --- a/clang/lib/CIR/CodeGen/ABIInfo.h +++ b/clang/lib/CIR/CodeGen/ABIInfo.h @@ -10,6 +10,8 @@ #define LLVM_CLANG_LIB_CIR_ABIINFO_H #include "clang/AST/Type.h" +#include "clang/Basic/LangOptions.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" namespace clang::CIRGen { @@ -39,6 +41,13 @@ class ABIInfo { // Implement the Type::IsPromotableIntegerType for ABI specific needs. The // only difference is that this consideres bit-precise integer types as well. bool isPromotableIntegerTypeForABI(clang::QualType Ty) const; + + /// Returns the optimal vector memory type based on the given vector type. For + /// example, on certain targets, a vector with 3 elements might be promoted to + /// one with 4 elements to improve performance. + virtual cir::VectorType + getOptimalVectorMemoryType(cir::VectorType T, + const clang::LangOptions &Opt) const; }; } // namespace clang::CIRGen diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 8ed7407f7e2b..38a880548202 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -173,9 +173,9 @@ static Address emitPointerWithAlignment(const Expr *expr, llvm_unreachable("NYI"); } - auto ElemTy = cgf.convertTypeForMem(expr->getType()->getPointeeType()); + auto eltTy = cgf.convertTypeForMem(expr->getType()->getPointeeType()); addr = cgf.getBuilder().createElementBitCast( - cgf.getLoc(expr->getSourceRange()), addr, ElemTy); + cgf.getLoc(expr->getSourceRange()), addr, eltTy); if (CE->getCastKind() == CK_AddressSpaceConversion) { assert(!cir::MissingFeatures::addressSpace()); llvm_unreachable("NYI"); @@ -616,6 +616,25 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr, LValueBaseInfo baseInfo, TBAAAccessInfo tbaaInfo, bool isInit, bool isNontemporal) { + assert(!cir::MissingFeatures::threadLocal() && "NYI"); + + auto eltTy = addr.getElementType(); + if (const auto *clangVecTy = ty->getAs()) { + // Boolean vectors use `iN` as storage type. + if (clangVecTy->isExtVectorBoolType()) { + llvm_unreachable("isExtVectorBoolType NYI"); + } + + // Handle vectors of size 3 like size 4 for better performance. + const auto vTy = cast(eltTy); + auto newVecTy = + CGM.getABIInfo().getOptimalVectorMemoryType(vTy, getLangOpts()); + + if (vTy != newVecTy) { + llvm_unreachable("NYI"); + } + } + value = emitToMemory(value, ty); LValue atomicLValue = @@ -626,26 +645,6 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr, return; } - mlir::Type SrcTy = value.getType(); - if (const auto *ClangVecTy = ty->getAs()) { - // TODO(CIR): this has fallen out of date with codegen - llvm_unreachable("NYI: Special treatment of 3-element vector store"); - // auto VecTy = dyn_cast(SrcTy); - // if (!CGM.getCodeGenOpts().PreserveVec3Type && - // ClangVecTy->getNumElements() == 3) { - // // Handle vec3 special. - // if (VecTy && VecTy.getSize() == 3) { - // // Our source is a vec3, do a shuffle vector to make it a vec4. - // value = builder.createVecShuffle(value.getLoc(), value, - // ArrayRef{0, 1, 2, -1}); - // SrcTy = cir::VectorType::get(VecTy.getContext(), VecTy.getEltType(), 4); - // } - // if (addr.getElementType() != SrcTy) { - // addr = addr.withElementType(SrcTy); - // } - // } - } - // Update the alloca with more info on initialization. assert(addr.getPointer() && "expected pointer to exist"); auto SrcAlloca = @@ -2917,40 +2916,36 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile, LValueBaseInfo baseInfo, TBAAAccessInfo tbaaInfo, bool isNontemporal) { - // TODO(CIR): this has fallen out of sync with codegen - // Atomic operations have to be done on integral types - LValue atomicLValue = - LValue::makeAddr(addr, ty, getContext(), baseInfo, tbaaInfo); - if (ty->isAtomicType() || LValueIsSuitableForInlineAtomic(atomicLValue)) { - llvm_unreachable("NYI"); - } + assert(!cir::MissingFeatures::threadLocal() && "NYI"); + auto eltTy = addr.getElementType(); - auto ElemTy = addr.getElementType(); + if (const auto *clangVecTy = ty->getAs()) { + // Boolean vectors use `iN` as storage type. + if (clangVecTy->isExtVectorBoolType()) { + llvm_unreachable("NYI"); + } - if (const auto *ClangVecTy = ty->getAs()) { // Handle vectors of size 3 like size 4 for better performance. - const auto VTy = cast(ElemTy); + const auto vTy = cast(eltTy); + auto newVecTy = + CGM.getABIInfo().getOptimalVectorMemoryType(vTy, getLangOpts()); - // TODO(CIR): this has fallen out of sync with codegen - llvm_unreachable("NYI: Special treatment of 3-element vector store"); - // if (!CGM.getCodeGenOpts().PreserveVec3Type && - // ClangVecTy->getNumElements() == 3) { - // auto loc = addr.getPointer().getLoc(); - // auto vec4Ty = cir::VectorType::get(VTy.getContext(), VTy.getEltType(), 4); - // Address Cast = addr.withElementType(vec4Ty); - // // Now load value. - // mlir::Value V = builder.createLoad(loc, Cast); + if (vTy != newVecTy) { + llvm_unreachable("NYI"); + } + } - // // Shuffle vector to get vec3. - // V = builder.createVecShuffle(loc, V, ArrayRef{0, 1, 2}); - // return emitFromMemory(V, ty); - // } + LValue atomicLValue = + LValue::makeAddr(addr, ty, getContext(), baseInfo, tbaaInfo); + if (ty->isAtomicType() || LValueIsSuitableForInlineAtomic(atomicLValue)) { + llvm_unreachable("NYI"); } + // TODO(cir): modernize this with addr.withElementType(convertTypeForLoadStore auto Ptr = addr.getPointer(); - if (mlir::isa(ElemTy)) { - ElemTy = cir::IntType::get(&getMLIRContext(), 8, true); - auto ElemPtrTy = cir::PointerType::get(&getMLIRContext(), ElemTy); + if (mlir::isa(eltTy)) { + eltTy = cir::IntType::get(&getMLIRContext(), 8, true); + auto ElemPtrTy = cir::PointerType::get(&getMLIRContext(), eltTy); Ptr = builder.create(loc, ElemPtrTy, cir::CastKind::bitcast, Ptr); } @@ -2962,7 +2957,6 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile, CGM.decorateOperationWithTBAA(loadOp, tbaaInfo); assert(!cir::MissingFeatures::emitScalarRangeCheck() && "NYI"); - return emitFromMemory(loadOp, ty); } diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index a427a297fd0d..c93a145f35ce 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -494,6 +494,10 @@ void CIRGenModule::setDSOLocal(CIRGlobalValueInterface GV) const { GV.setDSOLocal(shouldAssumeDSOLocal(*this, GV)); } +const ABIInfo &CIRGenModule::getABIInfo() { + return getTargetCIRGenInfo().getABIInfo(); +} + void CIRGenModule::emitGlobal(GlobalDecl GD) { llvm::TimeTraceScope scope("build CIR Global", [&]() -> std::string { auto *ND = dyn_cast(GD.getDecl()); diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index 4fa8d9dfbbcb..867dee754862 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -471,8 +471,8 @@ class CIRGenModule : public CIRGenTypeCache { /// NOTE: This should only be called for definitions. void setCommonAttributes(GlobalDecl GD, mlir::Operation *GV); - // TODO: this obviously overlaps with const TargetCIRGenInfo &getTargetCIRGenInfo(); + const ABIInfo &getABIInfo(); /// Helpers to convert Clang's SourceLocation to a MLIR Location. mlir::Location getLoc(clang::SourceLocation SLoc); diff --git a/clang/lib/CIR/CodeGen/TargetInfo.cpp b/clang/lib/CIR/CodeGen/TargetInfo.cpp index cadfe76a717c..d613167677a9 100644 --- a/clang/lib/CIR/CodeGen/TargetInfo.cpp +++ b/clang/lib/CIR/CodeGen/TargetInfo.cpp @@ -318,6 +318,15 @@ static bool classifyReturnType(const CIRGenCXXABI &CXXABI, CIRGenCXXABI &ABIInfo::getCXXABI() const { return CGT.getCXXABI(); } +cir::VectorType +ABIInfo::getOptimalVectorMemoryType(cir::VectorType T, + const clang::LangOptions &Opt) const { + if (T.getSize() == 3 && !Opt.PreserveVec3Type) { + llvm_unreachable("NYI"); + } + return T; +} + clang::ASTContext &ABIInfo::getContext() const { return CGT.getContext(); } cir::ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty, diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/ABIInfo.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/ABIInfo.h index 434070fd8157..c68392ed7c0b 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/ABIInfo.h +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/ABIInfo.h @@ -27,6 +27,7 @@ class LowerTypes; /// Target specific hooks for defining how a type should be passed or returned /// from functions. +/// FIXME(cir): this needs to be merged with clang/lib/CIR/CodeGen/ABIInfo.h class ABIInfo { protected: LowerTypes < diff --git a/clang/test/CIR/CodeGen/OpenCL/printf.cl b/clang/test/CIR/CodeGen/OpenCL/printf.cl index 180e194d8153..b539fce01c2b 100644 --- a/clang/test/CIR/CodeGen/OpenCL/printf.cl +++ b/clang/test/CIR/CodeGen/OpenCL/printf.cl @@ -14,7 +14,6 @@ // RUN: FileCheck -input-file=%t.30fp64.ll -check-prefixes=LLVM-FP64,LLVM-ALL %s // RUN: %clang_cc1 -fclangir -no-enable-noundef-analysis -cl-std=CL3.0 -cl-ext=-__opencl_c_fp64,-cl_khr_fp64 -triple spirv64-unknown-unknown -disable-llvm-passes -emit-llvm -fno-clangir-call-conv-lowering -o %t.30nofp64.ll %s // RUN: FileCheck -input-file=%t.30nofp64.ll -check-prefixes=LLVM-NOFP64,LLVM-ALL %s -// XFAIL: * typedef __attribute__((ext_vector_type(2))) float float2; typedef __attribute__((ext_vector_type(2))) half half2; diff --git a/clang/test/CIR/CodeGen/builtins-elementwise.c b/clang/test/CIR/CodeGen/builtins-elementwise.c index 191a4f8d8c3b..b790588605f4 100644 --- a/clang/test/CIR/CodeGen/builtins-elementwise.c +++ b/clang/test/CIR/CodeGen/builtins-elementwise.c @@ -3,7 +3,6 @@ // RUN: %clang_cc1 -triple aarch64-none-linux-android24 -fclangir \ // RUN: -emit-llvm %s -o %t.ll // RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s -// XFAIL: * typedef int vint4 __attribute__((ext_vector_type(4))); typedef float vfloat4 __attribute__((ext_vector_type(4))); diff --git a/clang/test/CIR/CodeGen/vectype.cpp b/clang/test/CIR/CodeGen/vectype.cpp index df4fe6ff9459..c47de5a7279f 100644 --- a/clang/test/CIR/CodeGen/vectype.cpp +++ b/clang/test/CIR/CodeGen/vectype.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s -// XFAIL: * typedef int vi4 __attribute__((vector_size(16))); typedef double vd2 __attribute__((vector_size(16))); diff --git a/clang/test/CIR/Lowering/ThroughMLIR/vectype.cpp b/clang/test/CIR/Lowering/ThroughMLIR/vectype.cpp index 57c18c67d44a..81c9fe063260 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/vectype.cpp +++ b/clang/test/CIR/Lowering/ThroughMLIR/vectype.cpp @@ -1,6 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s -// XFAIL: * typedef int vi4 __attribute__((vector_size(16))); diff --git a/clang/test/CIR/Lowering/vectype.cpp b/clang/test/CIR/Lowering/vectype.cpp index c457500694ce..eabac1c2fe92 100644 --- a/clang/test/CIR/Lowering/vectype.cpp +++ b/clang/test/CIR/Lowering/vectype.cpp @@ -2,7 +2,6 @@ // RUN: cir-opt %t.cir -cir-to-llvm -o %t.mlir // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ii // RUN: FileCheck --input-file=%t.mlir %s -// XFAIL: * typedef int vi4 __attribute__((vector_size(16))); typedef double vd2 __attribute__((vector_size(16)));