Index: clang/include/clang/Basic/DiagnosticFrontendKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -55,6 +55,9 @@ def warn_fe_backend_invalid_feature_flag : Warning< "feature flag '%0' must start with either '+' to enable the feature or '-'" " to disable it; flag ignored">, InGroup; +def warn_fe_backend_readonly_feature_flag : Warning< + "feature flag '%0' is ignored since the feature is read only">, + InGroup; def err_incompatible_fp_eval_method_options : Error< "option 'ffp-eval-method' cannot be used with option " Index: clang/include/clang/Basic/TargetInfo.h =================================================================== --- clang/include/clang/Basic/TargetInfo.h +++ clang/include/clang/Basic/TargetInfo.h @@ -29,6 +29,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Frontend/OpenMP/OMPGridValues.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/Support/DataTypes.h" @@ -267,6 +268,12 @@ // as a DataLayout object. void resetDataLayout(StringRef DL, const char *UserLabelPrefix = ""); + // Target features that are read-only and should not be disabled/enabled + // by command line options. Such features are for emitting predefined + // macros or checking availability of builtin functions and can be omitted + // in function attributes in IR. + llvm::StringSet<> ReadOnlyFeatures; + public: /// Construct a target for the given options. /// @@ -1394,6 +1401,11 @@ return false; } + /// Determine whether the given target feature is read only. + bool isReadOnlyFeature(StringRef Feature) const { + return ReadOnlyFeatures.count(Feature); + } + /// Identify whether this target supports multiversioning of functions, /// which requires support for cpu_supports and cpu_is functionality. bool supportsMultiVersioning() const { @@ -1711,6 +1723,9 @@ : std::optional(); } + /// Whether to support HIP image/texture API's. + virtual bool hasHIPImageSupport() const { return true; } + protected: /// Copy type and layout related info. void copyAuxTarget(const TargetInfo *Aux); Index: clang/lib/Basic/TargetInfo.cpp =================================================================== --- clang/lib/Basic/TargetInfo.cpp +++ clang/lib/Basic/TargetInfo.cpp @@ -528,6 +528,8 @@ // Apply the feature via the target. if (Name[0] != '+' && Name[0] != '-') Diags.Report(diag::warn_fe_backend_invalid_feature_flag) << Name; + else if (isReadOnlyFeature(Name.substr(1))) + Diags.Report(diag::warn_fe_backend_readonly_feature_flag) << Name; else setFeatureEnabled(Features, Name.substr(1), Name[0] == '+'); } Index: clang/lib/Basic/Targets/AMDGPU.h =================================================================== --- clang/lib/Basic/Targets/AMDGPU.h +++ clang/lib/Basic/Targets/AMDGPU.h @@ -46,6 +46,9 @@ /// Whether to use cumode or WGP mode. True for cumode. False for WGP mode. bool CUMode; + /// Whether having image instructions. + bool HasImage = false; + /// Target ID is device name followed by optional feature name postfixed /// by plus or minus sign delimitted by colon, e.g. gfx908:xnack+:sramecc-. /// If the target ID contains feature+, map it to true. @@ -449,6 +452,8 @@ CUMode = true; else if (F == "-cumode") CUMode = false; + else if (F == "+image-insts") + HasImage = true; bool IsOn = F.front() == '+'; StringRef Name = StringRef(F).drop_front(); if (!llvm::is_contained(TargetIDFeatures, Name)) @@ -469,6 +474,8 @@ return getCanonicalTargetID(getArchNameAMDGCN(GPUKind), OffloadArchFeatures); } + + bool hasHIPImageSupport() const override { return HasImage; } }; } // namespace targets Index: clang/lib/Basic/Targets/AMDGPU.cpp =================================================================== --- clang/lib/Basic/Targets/AMDGPU.cpp +++ clang/lib/Basic/Targets/AMDGPU.cpp @@ -244,6 +244,7 @@ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; CUMode = !(GPUFeatures & llvm::AMDGPU::FEATURE_WGP); + ReadOnlyFeatures.insert("image-insts"); } void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -2247,8 +2247,11 @@ getContext().getFunctionFeatureMap(FeatureMap, GD); // Produce the canonical string for this set of features. - for (const llvm::StringMap::value_type &Entry : FeatureMap) + for (const llvm::StringMap::value_type &Entry : FeatureMap) { + if (getTarget().isReadOnlyFeature(Entry.getKey())) + continue; Features.push_back((Entry.getValue() ? "+" : "-") + Entry.getKey().str()); + } // Now add the target-cpu and target-features to the function. // While we populated the feature map above, we still need to Index: clang/lib/Frontend/InitPreprocessor.cpp =================================================================== --- clang/lib/Frontend/InitPreprocessor.cpp +++ clang/lib/Frontend/InitPreprocessor.cpp @@ -583,8 +583,11 @@ Builder.defineMacro("__HIP_MEMORY_SCOPE_WORKGROUP", "3"); Builder.defineMacro("__HIP_MEMORY_SCOPE_AGENT", "4"); Builder.defineMacro("__HIP_MEMORY_SCOPE_SYSTEM", "5"); - if (LangOpts.CUDAIsDevice) + if (LangOpts.CUDAIsDevice) { Builder.defineMacro("__HIP_DEVICE_COMPILE__"); + if (!TI.hasHIPImageSupport()) + Builder.defineMacro("__HIP_NO_IMAGE_SUPPORT", "1"); + } if (LangOpts.GPUDefaultStream == LangOptions::GPUDefaultStreamKind::PerThread) Builder.defineMacro("HIP_API_PER_THREAD_DEFAULT_STREAM"); Index: clang/test/Driver/hip-macros.hip =================================================================== --- clang/test/Driver/hip-macros.hip +++ clang/test/Driver/hip-macros.hip @@ -42,3 +42,22 @@ // WARN-CUMODE-NOT: warning: ignoring '-mno-cumode' option as it is not currently supported for processor 'gfx906' [-Woption-ignored] // CUMODE-ON-DAG: #define __AMDGCN_CUMODE__ 1 // CUMODE-OFF-DAG: #define __AMDGCN_CUMODE__ 0 + +// RUN: %clang -E -dM --offload-arch=gfx90a --cuda-device-only -nogpuinc -nogpulib \ +// RUN: %s 2>&1 | FileCheck --check-prefixes=IMAGE,NOWARN %s +// RUN: %clang -E -dM --offload-arch=gfx1100 --cuda-device-only -nogpuinc -nogpulib \ +// RUN: %s 2>&1 | FileCheck --check-prefixes=IMAGE,NOWARN %s +// RUN: %clang -E -dM --offload-arch=gfx940 --cuda-device-only -nogpuinc -nogpulib \ +// RUN: %s 2>&1 | FileCheck --check-prefixes=NOIMAGE,NOWARN %s +// RUN: %clang -E -dM --offload-arch=gfx941 --cuda-device-only -nogpuinc -nogpulib \ +// RUN: %s 2>&1 | FileCheck --check-prefixes=NOIMAGE,NOWARN %s +// RUN: %clang -E -dM --offload-arch=gfx942 --cuda-device-only -nogpuinc -nogpulib \ +// RUN: %s 2>&1 | FileCheck --check-prefixes=NOIMAGE,NOWARN %s +// RUN: %clang -E -dM --offload-arch=gfx1100 --cuda-device-only -nogpuinc -nogpulib \ +// RUN: -Xclang -target-feature -Xclang "-image-insts" %s 2>&1 | FileCheck --check-prefixes=IMAGE,WARN %s +// RUN: %clang -E -dM --offload-arch=gfx940 --cuda-device-only -nogpuinc -nogpulib \ +// RUN: -Xclang -target-feature -Xclang "+image-insts" %s 2>&1 | FileCheck --check-prefixes=NOIMAGE,WARN %s +// NOWARN-NOT: warning +// WARN: warning: feature flag '{{[+|-]}}image-insts' is ignored since the feature is read only [-Winvalid-command-line-argument] +// IMAGE-NOT: #define __HIP_NO_IMAGE_SUPPORT +// NOIMAGE: #define __HIP_NO_IMAGE_SUPPORT 1 Index: llvm/lib/TargetParser/TargetParser.cpp =================================================================== --- llvm/lib/TargetParser/TargetParser.cpp +++ llvm/lib/TargetParser/TargetParser.cpp @@ -280,6 +280,7 @@ Features["gfx10-3-insts"] = true; Features["gfx11-insts"] = true; Features["atomic-fadd-rtn-insts"] = true; + Features["image-insts"] = true; break; case GK_GFX1036: case GK_GFX1035: @@ -302,6 +303,7 @@ Features["gfx9-insts"] = true; Features["gfx10-insts"] = true; Features["gfx10-3-insts"] = true; + Features["image-insts"] = true; Features["s-memrealtime"] = true; Features["s-memtime-inst"] = true; break; @@ -323,6 +325,7 @@ Features["gfx8-insts"] = true; Features["gfx9-insts"] = true; Features["gfx10-insts"] = true; + Features["image-insts"] = true; Features["s-memrealtime"] = true; Features["s-memtime-inst"] = true; break; @@ -334,7 +337,27 @@ Features["atomic-ds-pk-add-16-insts"] = true; Features["atomic-flat-pk-add-16-insts"] = true; Features["atomic-global-pk-add-bf16-inst"] = true; - [[fallthrough]]; + Features["gfx90a-insts"] = true; + Features["atomic-buffer-global-pk-add-f16-insts"] = true; + Features["atomic-fadd-rtn-insts"] = true; + Features["dot3-insts"] = true; + Features["dot4-insts"] = true; + Features["dot5-insts"] = true; + Features["dot6-insts"] = true; + Features["mai-insts"] = true; + Features["dl-insts"] = true; + Features["dot1-insts"] = true; + Features["dot2-insts"] = true; + Features["dot7-insts"] = true; + Features["dot10-insts"] = true; + Features["gfx9-insts"] = true; + Features["gfx8-insts"] = true; + Features["16-bit-insts"] = true; + Features["dpp"] = true; + Features["s-memrealtime"] = true; + Features["ci-insts"] = true; + Features["s-memtime-inst"] = true; + break; case GK_GFX90A: Features["gfx90a-insts"] = true; Features["atomic-buffer-global-pk-add-f16-insts"] = true; @@ -382,6 +405,7 @@ case GK_GFX602: case GK_GFX601: case GK_GFX600: + Features["image-insts"] = true; Features["s-memtime-inst"] = true; break; case GK_NONE: