llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-directx @llvm/pr-subscribers-clang-driver Author: Deric C. (Icohedron) <details> <summary>Changes</summary> Fixes #<!-- -->112270 Completed ACs: - `-res-may-alias` clang-dxc command-line option added - It inserts and sets a module metadata flag `dx.resmayalias` to 1 - Shader flag set appropriately: - CASE 1: command-line option -res-may-alias is NOT specified AND DXIL Version > 1.7 AND function uses UAVs - CASE 2: command-line option -res-may-alias is NOT specified AND DXIL Version <= 1.7 AND UAVs present globally - Add tests - A test (`res-may-not-alias-shadermodel6.8.ll`) for CASE 1 - A test (`res-may-not-alias-shadermodel6.7.ll`) for CASE 2 - A frontend test (`res-may-alias.hlsl`) for testing that the command-line option `-res-may-alias` sets the module metadata flag `dx.resmayalias` to 1, and does not set the module metadata flag `dx.resmayalias` if `-res-may-alias` is not given - Tests (`res-may-alias-0.ll`/`res-may-alias-1.ll`) for when the module metadata flag `dx.resmayalias` is set to 0 or 1 --- Full diff: https://github.com/llvm/llvm-project/pull/131070.diff 12 Files Affected: - (modified) clang/include/clang/Basic/CodeGenOptions.def (+3) - (modified) clang/include/clang/Driver/Options.td (+5) - (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+3) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+1) - (added) clang/test/CodeGenHLSL/res-may-alias.hlsl (+7) - (modified) llvm/lib/Target/DirectX/DXILShaderFlags.cpp (+37-6) - (modified) llvm/lib/Target/DirectX/DXILShaderFlags.h (+7-2) - (added) llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-0.ll (+39) - (added) llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-1.ll (+37) - (added) llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.7.ll (+33) - (added) llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.8.ll (+33) - (modified) llvm/test/CodeGen/DirectX/ShaderFlags/typed-uav-load-additional-formats.ll (+5-4) ``````````diff diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a7f5f1abbb825..a436c0ec98d5b 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -476,6 +476,9 @@ CODEGENOPT(ImportCallOptimization, 1, 0) /// (BlocksRuntime) on Windows. CODEGENOPT(StaticClosure, 1, 0) +/// Assume that UAVs/SRVs may alias +CODEGENOPT(ResMayAlias, 1, 0) + /// FIXME: Make DebugOptions its own top-level .def file. #include "DebugOptions.def" diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 66ae8f1c7f064..9c5fd2354f95e 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -9043,6 +9043,11 @@ def dxil_validator_version : Option<["/", "-"], "validator-version", KIND_SEPARA HelpText<"Override validator version for module. Format: <major.minor>;" "Default: DXIL.dll version or current internal version">, MarshallingInfoString<TargetOpts<"DxilValidatorVersion">, "\"1.8\"">; +def res_may_alias : Option<["/", "-"], "res-may-alias", KIND_FLAG>, + Group<dxc_Group>, Flags<[HelpHidden]>, + Visibility<[DXCOption, ClangOption, CC1Option]>, + HelpText<"Assume that UAVs/SRVs may alias">, + MarshallingInfoFlag<CodeGenOpts<"ResMayAlias">>; def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">, HelpText<"Set target profile">, Values<"ps_6_0, ps_6_1, ps_6_2, ps_6_3, ps_6_4, ps_6_5, ps_6_6, ps_6_7," diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 5916fa6183a27..6fd8bc295e8ca 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -283,10 +283,13 @@ void CGHLSLRuntime::addHLSLBufferLayoutType(const RecordType *StructType, void CGHLSLRuntime::finishCodeGen() { auto &TargetOpts = CGM.getTarget().getTargetOpts(); + auto &CodeGenOpts = CGM.getCodeGenOpts(); llvm::Module &M = CGM.getModule(); Triple T(M.getTargetTriple()); if (T.getArch() == Triple::ArchType::dxil) addDxilValVersion(TargetOpts.DxilValidatorVersion, M); + if (CodeGenOpts.ResMayAlias) + M.setModuleFlag(llvm::Module::ModFlagBehavior::Error, "dx.resmayalias", 1); generateGlobalCtorDtorCalls(); } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index fe172d923ac07..9be3939641cfc 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3959,6 +3959,7 @@ static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs, static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs, types::ID InputType) { const unsigned ForwardedArguments[] = {options::OPT_dxil_validator_version, + options::OPT_res_may_alias, options::OPT_D, options::OPT_I, options::OPT_O, diff --git a/clang/test/CodeGenHLSL/res-may-alias.hlsl b/clang/test/CodeGenHLSL/res-may-alias.hlsl new file mode 100644 index 0000000000000..53ee8ee4935d8 --- /dev/null +++ b/clang/test/CodeGenHLSL/res-may-alias.hlsl @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -res-may-alias -finclude-default-header -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=FLAG +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=NOFLAG + +// FLAG-DAG: ![[RMA:.*]] = !{i32 1, !"dx.resmayalias", i32 1} +// FLAG-DAG: !llvm.module.flags = !{{{.*}}![[RMA]]{{.*}}} + +// NOFLAG-NOT: dx.resmayalias diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index 31fbd66dfaa2d..b05ee53798524 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -74,7 +74,8 @@ static bool checkWaveOps(Intrinsic::ID IID) { /// \param I Instruction to check. void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, const Instruction &I, - DXILResourceTypeMap &DRTM) { + DXILResourceTypeMap &DRTM, + const ModuleMetadataInfo &MMDI) { if (!CSF.Doubles) CSF.Doubles = I.getType()->isDoubleTy(); @@ -116,8 +117,17 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, switch (II->getIntrinsicID()) { default: break; - case Intrinsic::dx_resource_handlefrombinding: - switch (DRTM[cast<TargetExtType>(II->getType())].getResourceKind()) { + case Intrinsic::dx_resource_handlefrombinding: { + dxil::ResourceTypeInfo &RTI = DRTM[cast<TargetExtType>(II->getType())]; + + // If -res-may-alias is NOT specified, and DXIL Ver > 1.7. + // Then set ResMayNotAlias if function uses UAVs. + if (!CSF.ResMayNotAlias && !ResMayAlias && + MMDI.DXILVersion > VersionTuple(1, 7) && RTI.isUAV()) { + CSF.ResMayNotAlias = true; + } + + switch (RTI.getResourceKind()) { case dxil::ResourceKind::StructuredBuffer: case dxil::ResourceKind::RawBuffer: CSF.EnableRawAndStructuredBuffers = true; @@ -126,6 +136,7 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, break; } break; + } case Intrinsic::dx_resource_load_typedbuffer: { dxil::ResourceTypeInfo &RTI = DRTM[cast<TargetExtType>(II->getArgOperand(0)->getType())]; @@ -151,7 +162,17 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, /// Construct ModuleShaderFlags for module Module M void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, + DXILBindingMap &DBM, const ModuleMetadataInfo &MMDI) { + + // Check if -res-may-alias was provided on the command line. + // The command line option will set the dx.resmayalias module flag to 1. + if (auto *RMA = mdconst::extract_or_null<ConstantInt>( + M.getModuleFlag("dx.resmayalias"))) { + if (RMA->getValue() != 0) + ResMayAlias = true; + } + CallGraph CG(M); // Compute Shader Flags Mask for all functions using post-order visit of SCC @@ -176,10 +197,16 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, continue; } + // If -res-may-alias is NOT specified, and DXIL Ver <= 1.7. + // Then set ResMayNotAlias to true if there are UAVs present globally. + if (!ResMayAlias && MMDI.DXILVersion <= VersionTuple(1, 7)) { + SCCSF.ResMayNotAlias = !DBM.uavs().empty(); + } + ComputedShaderFlags CSF; for (const auto &BB : *F) for (const auto &I : BB) - updateFunctionFlags(CSF, I, DRTM); + updateFunctionFlags(CSF, I, DRTM, MMDI); // Update combined shader flags mask for all functions in this SCC SCCSF.merge(CSF); @@ -249,10 +276,11 @@ AnalysisKey ShaderFlagsAnalysis::Key; ModuleShaderFlags ShaderFlagsAnalysis::run(Module &M, ModuleAnalysisManager &AM) { DXILResourceTypeMap &DRTM = AM.getResult<DXILResourceTypeAnalysis>(M); + DXILBindingMap &DBM = AM.getResult<DXILResourceBindingAnalysis>(M); const ModuleMetadataInfo MMDI = AM.getResult<DXILMetadataAnalysis>(M); ModuleShaderFlags MSFI; - MSFI.initialize(M, DRTM, MMDI); + MSFI.initialize(M, DRTM, DBM, MMDI); return MSFI; } @@ -282,16 +310,19 @@ PreservedAnalyses ShaderFlagsAnalysisPrinter::run(Module &M, bool ShaderFlagsAnalysisWrapper::runOnModule(Module &M) { DXILResourceTypeMap &DRTM = getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap(); + DXILBindingMap &DBM = + getAnalysis<DXILResourceBindingWrapperPass>().getBindingMap(); const ModuleMetadataInfo MMDI = getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata(); - MSFI.initialize(M, DRTM, MMDI); + MSFI.initialize(M, DRTM, DBM, MMDI); return false; } void ShaderFlagsAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequiredTransitive<DXILResourceTypeWrapperPass>(); + AU.addRequiredTransitive<DXILResourceBindingWrapperPass>(); AU.addRequired<DXILMetadataAnalysisWrapperPass>(); } diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.h b/llvm/lib/Target/DirectX/DXILShaderFlags.h index abf7cc86259ed..b47c79cb293a5 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.h +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.h @@ -28,6 +28,7 @@ namespace llvm { class Module; class GlobalVariable; class DXILResourceTypeMap; +class DXILBindingMap; namespace dxil { @@ -84,12 +85,16 @@ struct ComputedShaderFlags { }; struct ModuleShaderFlags { - void initialize(Module &, DXILResourceTypeMap &DRTM, + void initialize(Module &, DXILResourceTypeMap &DRTM, DXILBindingMap &DBM, const ModuleMetadataInfo &MMDI); const ComputedShaderFlags &getFunctionFlags(const Function *) const; const ComputedShaderFlags &getCombinedFlags() const { return CombinedSFMask; } private: + // A bool to indicate if the -res-may-alias flag was passed to clang-dxc. + // A module flag "dx.resmayalias" is set to 1 if true. + // This bool is used in the logic for setting the flag ResMayNotAlias. + bool ResMayAlias = false; /// Map of Function-Shader Flag Mask pairs representing properties of each of /// the functions in the module. Shader Flags of each function represent both /// module-level and function-level flags @@ -97,7 +102,7 @@ struct ModuleShaderFlags { /// Combined Shader Flag Mask of all functions of the module ComputedShaderFlags CombinedSFMask{}; void updateFunctionFlags(ComputedShaderFlags &, const Instruction &, - DXILResourceTypeMap &); + DXILResourceTypeMap &, const ModuleMetadataInfo &); }; class ShaderFlagsAnalysis : public AnalysisInfoMixin<ShaderFlagsAnalysis> { diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-0.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-0.ll new file mode 100644 index 0000000000000..29901de7f8e37 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-0.ll @@ -0,0 +1,39 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s + +target triple = "dxil-pc-shadermodel6.8-library" + +; CHECK: Combined Shader Flags for Module +; CHECK-NEXT: Shader Flags Value: 0x200000010 + +; CHECK: Note: extra DXIL module flags: +; CHECK: Raw and Structured buffers +; CHECK: Any UAV may not alias any other UAV +; + +; CHECK: Function loadUAV : 0x20000000 +define float @loadUAV() #0 { + %res = call target("dx.TypedBuffer", float, 1, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) + %load = call {float, i1} @llvm.dx.resource.load.typedbuffer( + target("dx.TypedBuffer", float, 1, 0, 0) %res, i32 0) + %val = extractvalue {float, i1} %load, 0 + ret float %val +} + +; CHECK: Function loadSRV : 0x00000010 +define float @loadSRV() #0 { + %res = tail call target("dx.RawBuffer", float, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) + %load = call {float, i1} @llvm.dx.resource.load.rawbuffer( + target("dx.RawBuffer", float, 0, 0) %res, i32 0, i32 0) + %val = extractvalue { float, i1 } %load, 0 + ret float %val +} + +!llvm.module.flags = !{!0} + +; dx.resmayalias should never appear with a value of 0. +; But if it does, ensure that it has no effect. +!0 = !{i32 1, !"dx.resmayalias", i32 0} + +attributes #0 = { convergent norecurse nounwind "hlsl.export"} diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-1.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-1.ll new file mode 100644 index 0000000000000..98a8dd06f6020 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-1.ll @@ -0,0 +1,37 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s + +target triple = "dxil-pc-shadermodel6.8-library" + +; CHECK: Combined Shader Flags for Module +; CHECK-NEXT: Shader Flags Value: 0x00000010 + +; CHECK: Note: extra DXIL module flags: +; CHECK: Raw and Structured buffers +; CHECK-NOT: Any UAV may not alias any other UAV +; + +; CHECK: Function loadUAV : 0x00000000 +define float @loadUAV() #0 { + %res = call target("dx.TypedBuffer", float, 1, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) + %load = call {float, i1} @llvm.dx.resource.load.typedbuffer( + target("dx.TypedBuffer", float, 1, 0, 0) %res, i32 0) + %val = extractvalue {float, i1} %load, 0 + ret float %val +} + +; CHECK: Function loadSRV : 0x00000010 +define float @loadSRV() #0 { + %res = tail call target("dx.RawBuffer", float, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) + %load = call {float, i1} @llvm.dx.resource.load.rawbuffer( + target("dx.RawBuffer", float, 0, 0) %res, i32 0, i32 0) + %val = extractvalue { float, i1 } %load, 0 + ret float %val +} + +!llvm.module.flags = !{!0} + +!0 = !{i32 1, !"dx.resmayalias", i32 1} + +attributes #0 = { convergent norecurse nounwind "hlsl.export"} diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.7.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.7.ll new file mode 100644 index 0000000000000..ab3eea71bf8f0 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.7.ll @@ -0,0 +1,33 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s + +target triple = "dxil-pc-shadermodel6.7-library" + +; CHECK: Combined Shader Flags for Module +; CHECK-NEXT: Shader Flags Value: 0x200000010 + +; CHECK: Note: extra DXIL module flags: +; CHECK: Raw and Structured buffers +; CHECK: Any UAV may not alias any other UAV +; + +; CHECK: Function loadUAV : 0x200000000 +define float @loadUAV() #0 { + %res = call target("dx.TypedBuffer", float, 1, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) + %load = call {float, i1} @llvm.dx.resource.load.typedbuffer( + target("dx.TypedBuffer", float, 1, 0, 0) %res, i32 0) + %val = extractvalue {float, i1} %load, 0 + ret float %val +} + +; CHECK: Function loadSRV : 0x200000010 +define float @loadSRV() #0 { + %res = tail call target("dx.RawBuffer", float, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) + %load = call {float, i1} @llvm.dx.resource.load.rawbuffer( + target("dx.RawBuffer", float, 0, 0) %res, i32 0, i32 0) + %val = extractvalue { float, i1 } %load, 0 + ret float %val +} + +attributes #0 = { convergent norecurse nounwind "hlsl.export"} diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.8.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.8.ll new file mode 100644 index 0000000000000..fb5e234f0bd93 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.8.ll @@ -0,0 +1,33 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s + +target triple = "dxil-pc-shadermodel6.8-library" + +; CHECK: Combined Shader Flags for Module +; CHECK-NEXT: Shader Flags Value: 0x200000010 + +; CHECK: Note: extra DXIL module flags: +; CHECK: Raw and Structured buffers +; CHECK: Any UAV may not alias any other UAV +; + +; CHECK: Function loadUAV : 0x20000000 +define float @loadUAV() #0 { + %res = call target("dx.TypedBuffer", float, 1, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) + %load = call {float, i1} @llvm.dx.resource.load.typedbuffer( + target("dx.TypedBuffer", float, 1, 0, 0) %res, i32 0) + %val = extractvalue {float, i1} %load, 0 + ret float %val +} + +; CHECK: Function loadSRV : 0x00000010 +define float @loadSRV() #0 { + %res = tail call target("dx.RawBuffer", float, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) + %load = call {float, i1} @llvm.dx.resource.load.rawbuffer( + target("dx.RawBuffer", float, 0, 0) %res, i32 0, i32 0) + %val = extractvalue { float, i1 } %load, 0 + ret float %val +} + +attributes #0 = { convergent norecurse nounwind "hlsl.export"} diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/typed-uav-load-additional-formats.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/typed-uav-load-additional-formats.ll index 060d54f961c70..96f80f531fa32 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/typed-uav-load-additional-formats.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/typed-uav-load-additional-formats.ll @@ -8,12 +8,13 @@ target triple = "dxil-pc-shadermodel6.7-library" ; CHECK-OBJ: TypedUAVLoadAdditionalFormats: true ; CHECK: Combined Shader Flags for Module -; CHECK-NEXT: Shader Flags Value: 0x00002000 +; CHECK-NEXT: Shader Flags Value: 0x200002000 ; CHECK: Note: shader requires additional functionality: ; CHECK: Typed UAV Load Additional Formats +; CHECK: Any UAV may not alias any other UAV -; CHECK: Function multicomponent : 0x00002000 +; CHECK: Function multicomponent : 0x200002000 define <4 x float> @multicomponent() #0 { %res = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) @@ -23,7 +24,7 @@ define <4 x float> @multicomponent() #0 { ret <4 x float> %val } -; CHECK: Function onecomponent : 0x00000000 +; CHECK: Function onecomponent : 0x200000000 define float @onecomponent() #0 { %res = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) @@ -33,7 +34,7 @@ define float @onecomponent() #0 { ret float %val } -; CHECK: Function noload : 0x00000000 +; CHECK: Function noload : 0x200000000 define void @noload(<4 x float> %val) #0 { %res = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) `````````` </details> https://github.com/llvm/llvm-project/pull/131070 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits