https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/123411
>From 6aba475e4af789fc03594560ad9937e3502cce51 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Fri, 17 Jan 2025 13:31:01 -0800 Subject: [PATCH 1/2] [HLSL] Add address space `hlsl_constant(2)` for constant buffer declarations --- clang/include/clang/Basic/AddressSpaces.h | 1 + clang/lib/AST/TypePrinter.cpp | 2 + clang/lib/Basic/Targets/AArch64.h | 1 + clang/lib/Basic/Targets/AMDGPU.cpp | 1 + clang/lib/Basic/Targets/DirectX.h | 1 + clang/lib/Basic/Targets/NVPTX.h | 1 + clang/lib/Basic/Targets/SPIR.h | 2 + clang/lib/Basic/Targets/SystemZ.h | 1 + clang/lib/Basic/Targets/TCE.h | 1 + clang/lib/Basic/Targets/WebAssembly.h | 1 + clang/lib/Basic/Targets/X86.h | 1 + clang/lib/CodeGen/CGHLSLRuntime.cpp | 16 -------- clang/lib/Sema/SemaHLSL.cpp | 15 ++++++-- .../ast-dump-comment-cbuffer-tbuffer.hlsl | 16 ++++---- clang/test/AST/HLSL/cbuffer.hlsl | 24 ++++++------ clang/test/AST/HLSL/packoffset.hlsl | 38 +++++++++---------- clang/test/AST/HLSL/pch_hlsl_buffer.hlsl | 12 +++--- .../test/AST/HLSL/resource_binding_attr.hlsl | 8 ++-- clang/test/CodeGenHLSL/cbuf.hlsl | 13 +++++-- clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl | 8 +++- .../static_global_and_function_in_cb.hlsl | 14 ++++--- 21 files changed, 97 insertions(+), 80 deletions(-) diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h index 7b723d508fff17..d18bfe54931f93 100644 --- a/clang/include/clang/Basic/AddressSpaces.h +++ b/clang/include/clang/Basic/AddressSpaces.h @@ -58,6 +58,7 @@ enum class LangAS : unsigned { // HLSL specific address spaces. hlsl_groupshared, + hlsl_constant, // Wasm specific address spaces. wasm_funcref, diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index a850410ffc8468..6cad74fef3fe33 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2556,6 +2556,8 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) { return "__funcref"; case LangAS::hlsl_groupshared: return "groupshared"; + case LangAS::hlsl_constant: + return "hlsl_constant"; default: return std::to_string(toTargetAddressSpace(AS)); } diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index ecf80b23a508c9..600940f5e4e23c 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -44,6 +44,7 @@ static const unsigned ARM64AddrSpaceMap[] = { static_cast<unsigned>(AArch64AddrSpace::ptr32_uptr), static_cast<unsigned>(AArch64AddrSpace::ptr64), 0, // hlsl_groupshared + 0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 99f8f2944e2796..824134d52ec139 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -83,6 +83,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared + llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_constant }; } // namespace targets diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h index ab22d1281a4df7..4e6bc0e040398b 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -42,6 +42,7 @@ static const unsigned DirectXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 3, // hlsl_groupshared + 2, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h index d81b89a7f24ac0..c6531148fe30ce 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -46,6 +46,7 @@ static const unsigned NVPTXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 5a328b9ceeb1d1..c0849b69dcdb32 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -47,6 +47,7 @@ static const unsigned SPIRDefIsPrivMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 2, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref @@ -80,6 +81,7 @@ static const unsigned SPIRDefIsGenMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index e6405f174f660f..66a1bf6a38b51b 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -42,6 +42,7 @@ static const unsigned ZOSAddressMap[] = { 1, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant 0 // wasm_funcref }; diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h index d6280b02f07b25..edec30bf69de0c 100644 --- a/clang/lib/Basic/Targets/TCE.h +++ b/clang/lib/Basic/Targets/TCE.h @@ -51,6 +51,7 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index 0a14da6a277b8e..cfecc59ac75fd9 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -42,6 +42,7 @@ static const unsigned WebAssemblyAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant 20, // wasm_funcref }; diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 2c200e64a3d84d..8bd54e362526fb 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -46,6 +46,7 @@ static const unsigned X86AddrSpaceMap[] = { 271, // ptr32_uptr 272, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 5679bd71581795..127bd4a7fc27f0 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -100,22 +100,6 @@ GlobalVariable *replaceBuffer(CGHLSLRuntime::Buffer &Buf) { llvm::formatv("{0}{1}", Buf.Name, Buf.IsCBuffer ? ".cb." : ".tb."), GlobalValue::NotThreadLocal); - IRBuilder<> B(CBGV->getContext()); - Value *ZeroIdx = B.getInt32(0); - // Replace Const use with CB use. - for (auto &[GV, Offset] : Buf.Constants) { - Value *GEP = - B.CreateGEP(Buf.LayoutStruct, CBGV, {ZeroIdx, B.getInt32(Offset)}); - - assert(Buf.LayoutStruct->getElementType(Offset) == GV->getValueType() && - "constant type mismatch"); - - // Replace. - GV->replaceAllUsesWith(GEP); - // Erase GV. - GV->removeDeadConstantUsers(); - GV->eraseFromParent(); - } return CBGV; } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 9bbd0ad1eb4a64..372db586f8d8ea 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -24,6 +24,7 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" @@ -455,14 +456,22 @@ void createHostLayoutStructForBuffer(Sema &S, HLSLBufferDecl *BufDecl) { LS->setImplicit(true); LS->startDefinition(); - for (const Decl *D : BufDecl->decls()) { - const VarDecl *VD = dyn_cast<VarDecl>(D); + for (Decl *D : BufDecl->decls()) { + VarDecl *VD = dyn_cast<VarDecl>(D); if (!VD || VD->getStorageClass() == SC_Static) continue; const Type *Ty = VD->getType()->getUnqualifiedDesugaredType(); if (FieldDecl *FD = createFieldForHostLayoutStruct( - S, Ty, VD->getIdentifier(), LS, BufDecl)) + S, Ty, VD->getIdentifier(), LS, BufDecl)) { + // add the field decl to the layout struct LS->addDecl(FD); + // update address space of the original decl to hlsl_constant + // and disable initialization + QualType NewTy = + AST.getAddrSpaceQualType(VD->getType(), LangAS::hlsl_constant); + VD->setType(NewTy); + VD->setInit(nullptr); + } } LS->completeDefinition(); BufDecl->addDecl(LS); diff --git a/clang/test/AST/HLSL/ast-dump-comment-cbuffer-tbuffer.hlsl b/clang/test/AST/HLSL/ast-dump-comment-cbuffer-tbuffer.hlsl index aebb7c0e8da334..3cca808ae75b63 100644 --- a/clang/test/AST/HLSL/ast-dump-comment-cbuffer-tbuffer.hlsl +++ b/clang/test/AST/HLSL/ast-dump-comment-cbuffer-tbuffer.hlsl @@ -11,11 +11,11 @@ cbuffer A { // JSON: "kind": "VarDecl", // JSON: "name": "a", - // JSON: "qualType": "float" + // JSON: "qualType": "hlsl_constant float" float a; // JSON: "kind": "VarDecl", // JSON: "name": "b", - // JSON: "qualType": "int" + // JSON: "qualType": "hlsl_constant int" int b; } @@ -29,11 +29,11 @@ cbuffer A { tbuffer B { // JSON: "kind": "VarDecl", // JSON: "name": "c", - // JSON: "qualType": "float" + // JSON: "qualType": "hlsl_constant float" float c; // JSON: "kind": "VarDecl", // JSON: "name": "d", - // JSON: "qualType": "int" + // JSON: "qualType": "hlsl_constant int" int d; } @@ -43,8 +43,8 @@ tbuffer B { // AST-NEXT: FullComment // AST-NEXT: ParagraphComment // AST-NEXT: TextComment {{.*}} Text=" CBuffer decl." -// AST-NEXT: VarDecl {{.*}} a 'float' -// AST-NEXT: VarDecl {{.*}} b 'int' +// AST-NEXT: VarDecl {{.*}} a 'hlsl_constant float' +// AST-NEXT: VarDecl {{.*}} b 'hlsl_constant int' // AST-NEXT: CXXRecordDecl {{.*}} implicit class __layout.A definition // AST: FieldDecl {{.*}} a 'float' // AST-NEXT: FieldDecl {{.*}} b 'int' @@ -55,8 +55,8 @@ tbuffer B { // AST-NEXT: FullComment // AST-NEXT: ParagraphComment // AST-NEXT: TextComment {{.*}} Text=" TBuffer decl." -// AST-NEXT: VarDecl {{.*}} c 'float' -// AST-NEXT: VarDecl {{.*}} d 'int' +// AST-NEXT: VarDecl {{.*}} c 'hlsl_constant float' +// AST-NEXT: VarDecl {{.*}} d 'hlsl_constant int' // AST-NEXT: CXXRecordDecl {{.*}} implicit class __layout.B definition // AST: FieldDecl {{.*}} c 'float' // AST-NEXT: FieldDecl {{.*}} d 'int' diff --git a/clang/test/AST/HLSL/cbuffer.hlsl b/clang/test/AST/HLSL/cbuffer.hlsl index a20485606a79d0..1d933fcb1adebd 100644 --- a/clang/test/AST/HLSL/cbuffer.hlsl +++ b/clang/test/AST/HLSL/cbuffer.hlsl @@ -39,7 +39,7 @@ typedef float EmptyArrayTypedef[10][0]; // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} col:9 used a1 'float' + // CHECK: VarDecl {{.*}} col:9 used a1 'hlsl_constant float' float a1; // CHECK: CXXRecordDecl {{.*}} implicit class __layout.CB definition // CHECK: FieldDecl {{.*}} a1 'float' @@ -50,7 +50,7 @@ cbuffer CB { // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} col:9 used a2 'float' + // CHECK: VarDecl {{.*}} col:9 used a2 'hlsl_constant float' float a2; // CHECK: VarDecl {{.*}} col:19 b2 'RWBuffer<float>':'hlsl::RWBuffer<float>' RWBuffer<float> b2; @@ -58,7 +58,7 @@ cbuffer CB { EmptyStruct c2; // CHECK: VarDecl {{.*}} col:9 d2 'float[0]' float d2[0]; - // CHECK: VarDecl {{.*}} col:9 e2 'float' + // CHECK: VarDecl {{.*}} col:9 e2 'hlsl_constant float' float e2; // CHECK: CXXRecordDecl {{.*}} implicit class __layout.CB.1 definition // CHECK: FieldDecl {{.*}} a2 'float' @@ -70,11 +70,11 @@ cbuffer CB { // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} col:5 used s1 'A' + // CHECK: VarDecl {{.*}} col:5 used s1 'hlsl_constant A' A s1; - // CHECK: VarDecl {{.*}} col:5 s2 'B' + // CHECK: VarDecl {{.*}} col:5 s2 'hlsl_constant B' B s2; - // CHECK: VarDecl {{.*}} col:12 s3 'CTypedef':'C + // CHECK: VarDecl {{.*}} col:12 s3 'CTypedef':'C' CTypedef s3; // CHECK: CXXRecordDecl {{.*}} implicit class __layout.B definition // CHECK: FieldDecl {{.*}} a 'float' @@ -88,7 +88,7 @@ cbuffer CB { // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} s4 'D' + // CHECK: VarDecl {{.*}} s4 'hlsl_constant D' D s4; // CHECK: CXXRecordDecl {{.*}} implicit class __layout.D definition // CHECK: FieldDecl {{.*}} b 'float' @@ -103,9 +103,9 @@ cbuffer CB { // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} s5 'E' + // CHECK: VarDecl {{.*}} s5 'hlsl_constant E' E s5; - // CHECK: VarDecl {{.*}} s6 'BTypedef':'B' + // CHECK: VarDecl {{.*}} s6 'hlsl_constant BTypedef':'hlsl_constant B' BTypedef s6; // CHECK: CXXRecordDecl {{.*}} implicit class __layout.E definition // CHECK: FieldDecl {{.*}} c 'float' @@ -139,7 +139,7 @@ cbuffer CB { // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} s8 'F' + // CHECK: VarDecl {{.*}} s8 'hlsl_constant F' F s8; // CHECK: CXXRecordDecl {{.*}} implicit class __layout.F definition // CHECK: public 'A' @@ -161,7 +161,7 @@ cbuffer CB { // CHECK: FieldDecl {{.*}} f 'RWBuffer<float>':'hlsl::RWBuffer<float>' RWBuffer<float> f; } s9; - // CHECK: VarDecl {{.*}} s9 'struct (unnamed struct at {{.*}}cbuffer.hlsl:156:3 + // CHECK: VarDecl {{.*}} s9 'hlsl_constant struct (unnamed struct at {{.*}}cbuffer.hlsl:156:3 // CHECK: CXXRecordDecl {{.*}} struct definition struct { // CHECK: FieldDecl {{.*}} g 'int' @@ -169,7 +169,7 @@ cbuffer CB { // CHECK: FieldDecl {{.*}} f 'RWBuffer<float>':'hlsl::RWBuffer<float>' RWBuffer<float> f; } s10; - // CHECK: VarDecl {{.*}} s10 'struct (unnamed struct at {{.*}}cbuffer.hlsl:166:3 + // CHECK: VarDecl {{.*}} s10 'hlsl_constant struct (unnamed struct at {{.*}}cbuffer.hlsl:166:3 // CHECK: CXXRecordDecl {{.*}} implicit class __layout.anon definition // CHECK: FieldDecl {{.*}} e 'float' // CHECK: CXXRecordDecl {{.*}} implicit class __layout.anon.1 definition diff --git a/clang/test/AST/HLSL/packoffset.hlsl b/clang/test/AST/HLSL/packoffset.hlsl index 9c928bd6d922ed..a9bb90bb386f9c 100644 --- a/clang/test/AST/HLSL/packoffset.hlsl +++ b/clang/test/AST/HLSL/packoffset.hlsl @@ -6,13 +6,13 @@ cbuffer A { // CHECK-NEXT:-HLSLResourceClassAttr {{.*}} <<invalid sloc>> Implicit CBuffer // CHECK-NEXT:-HLSLResourceAttr {{.*}} <<invalid sloc>> Implicit CBuffer - // CHECK-NEXT: VarDecl {{.*}} A1 'float4' + // CHECK-NEXT: VarDecl {{.*}} A1 'hlsl_constant float4' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 0 float4 A1 : packoffset(c); - // CHECK-NEXT: VarDecl {{.*}} col:11 A2 'float' + // CHECK-NEXT: VarDecl {{.*}} col:11 A2 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 1 0 float A2 : packoffset(c1); - // CHECK-NEXT: VarDecl {{.*}} col:11 A3 'float' + // CHECK-NEXT: VarDecl {{.*}} col:11 A3 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 1 1 float A3 : packoffset(c1.y); } @@ -20,13 +20,13 @@ cbuffer A // CHECK: HLSLBufferDecl {{.*}} cbuffer B cbuffer B { - // CHECK: VarDecl {{.*}} B0 'float' + // CHECK: VarDecl {{.*}} B0 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 1 float B0 : packoffset(c0.g); - // CHECK-NEXT: VarDecl {{.*}} B1 'double' + // CHECK-NEXT: VarDecl {{.*}} B1 'hlsl_constant double' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 2 double B1 : packoffset(c0.b); - // CHECK-NEXT: VarDecl {{.*}} B2 'half' + // CHECK-NEXT: VarDecl {{.*}} B2 'hlsl_constant half' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 0 half B2 : packoffset(c0.r); } @@ -34,13 +34,13 @@ cbuffer B // CHECK: HLSLBufferDecl {{.*}} cbuffer C cbuffer C { - // CHECK: VarDecl {{.*}} C0 'float' + // CHECK: VarDecl {{.*}} C0 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 1 float C0 : packoffset(c0.y); - // CHECK-NEXT: VarDecl {{.*}} C1 'float2' + // CHECK-NEXT: VarDecl {{.*}} C1 'hlsl_constant float2' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 2 float2 C1 : packoffset(c0.z); - // CHECK-NEXT: VarDecl {{.*}} C2 'half' + // CHECK-NEXT: VarDecl {{.*}} C2 'hlsl_constant half' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 half C2 : packoffset(c0.x); } @@ -49,16 +49,16 @@ cbuffer C // CHECK: HLSLBufferDecl {{.*}} cbuffer D cbuffer D { - // CHECK: VarDecl {{.*}} D0 'float' + // CHECK: VarDecl {{.*}} D0 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 1 float D0 : packoffset(c0.y); - // CHECK-NEXT: VarDecl {{.*}} D1 'float[2]' + // CHECK-NEXT: VarDecl {{.*}} D1 'hlsl_constant float[2]' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 1 0 float D1[2] : packoffset(c1.x); - // CHECK-NEXT: VarDecl {{.*}} D2 'half3' + // CHECK-NEXT: VarDecl {{.*}} D2 'hlsl_constant half3' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 2 1 half3 D2 : packoffset(c2.y); - // CHECK-NEXT: VarDecl {{.*}} D3 'double' + // CHECK-NEXT: VarDecl {{.*}} D3 'hlsl_constant double' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 2 double D3 : packoffset(c0.z); } @@ -71,13 +71,13 @@ struct ST { // CHECK: HLSLBufferDecl {{.*}} cbuffer S cbuffer S { - // CHECK: VarDecl {{.*}} S0 'float' + // CHECK: VarDecl {{.*}} S0 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 1 float S0 : packoffset(c0.y); - // CHECK: VarDecl {{.*}} S1 'ST' + // CHECK: VarDecl {{.*}} S1 'hlsl_constant ST' // CHECK: HLSLPackOffsetAttr {{.*}} 1 0 ST S1 : packoffset(c1); - // CHECK: VarDecl {{.*}} S2 'double2' + // CHECK: VarDecl {{.*}} S2 'hlsl_constant double2' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 2 0 double2 S2 : packoffset(c2); } @@ -90,13 +90,13 @@ struct ST2 { // CHECK: HLSLBufferDecl {{.*}} cbuffer S2 cbuffer S2 { - // CHECK: VarDecl {{.*}} S20 'float' + // CHECK: VarDecl {{.*}} S20 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 3 float S20 : packoffset(c0.a); - // CHECK: VarDecl {{.*}} S21 'ST2' + // CHECK: VarDecl {{.*}} S21 'hlsl_constant ST2' // CHECK: HLSLPackOffsetAttr {{.*}} 1 0 ST2 S21 : packoffset(c1); - // CHECK: VarDecl {{.*}} S22 'half' + // CHECK: VarDecl {{.*}} S22 'hlsl_constant half' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 3 1 half S22 : packoffset(c3.y); } diff --git a/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl b/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl index 02310c068c166e..3bfe8467544928 100644 --- a/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl +++ b/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl @@ -20,22 +20,22 @@ float foo() { // CHECK: HLSLBufferDecl {{.*}} line:7:9 imported <undeserialized declarations> cbuffer A // CHECK-NEXT: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK-NEXT: HLSLResourceAttr {{.*}} Implicit CBuffer -// CHECK-NEXT: VarDecl 0x[[A:[0-9a-f]+]] {{.*}} imported used a 'float' +// CHECK-NEXT: VarDecl 0x[[A:[0-9a-f]+]] {{.*}} imported used a 'hlsl_constant float' // CHECK-NEXT: CXXRecordDecl {{.*}} imported implicit <undeserialized declarations> class __layout.A definition // CHECK: FieldDecl {{.*}} imported a 'float' // CHECK: HLSLBufferDecl {{.*}} line:11:9 imported <undeserialized declarations> tbuffer B // CHECK-NEXT: HLSLResourceClassAttr {{.*}} Implicit SRV // CHECK-NEXT: HLSLResourceAttr {{.*}} Implicit TBuffer -// CHECK-NEXT: VarDecl 0x[[B:[0-9a-f]+]] {{.*}} imported used b 'float' -// CHECK-NEXT: CXXRecordDecl 0x{{[0-9a-f]+}} {{.*}} imported implicit <undeserialized declarations> class __layout.B definition -// CHECK: FieldDecl 0x{{[0-9a-f]+}} {{.*}} imported b 'float' +// CHECK-NEXT: VarDecl 0x[[B:[0-9a-f]+]] {{.*}} imported used b 'hlsl_constant float' +// CHECK-NEXT: CXXRecordDecl {{.*}} imported implicit <undeserialized declarations> class __layout.B definition +// CHECK: FieldDecl {{.*}} imported b 'float' // CHECK-NEXT: FunctionDecl {{.*}} line:15:7 imported foo 'float ()' // CHECK-NEXT: CompoundStmt {{.*}} // CHECK-NEXT: ReturnStmt {{.*}} // CHECK-NEXT: BinaryOperator {{.*}} 'float' '+' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <LValueToRValue> -// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue Var 0x[[A]] 'a' 'float' +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl_constant float' lvalue Var 0x[[A]] 'a' 'hlsl_constant float' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <LValueToRValue> -// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue Var 0x[[B]] 'b' 'float' +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl_constant float' lvalue Var 0x[[B]] 'b' 'hlsl_constant float' diff --git a/clang/test/AST/HLSL/resource_binding_attr.hlsl b/clang/test/AST/HLSL/resource_binding_attr.hlsl index 13957ad3c1fcc7..6fac903f75e18e 100644 --- a/clang/test/AST/HLSL/resource_binding_attr.hlsl +++ b/clang/test/AST/HLSL/resource_binding_attr.hlsl @@ -4,7 +4,7 @@ // CHECK-NEXT:HLSLResourceClassAttr 0x[[CB:[0-9a-f]+]] {{.*}} Implicit CBuffer // CHECK-NEXT:HLSLResourceAttr 0x[[CB:[0-9a-f]+]] {{.*}} Implicit CBuffer // CHECK-NEXT:HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:14> "b3" "space2" -// CHECK-NEXT:VarDecl 0x[[A:[0-9a-f]+]] {{.*}} col:9 used a 'float' +// CHECK-NEXT:VarDecl 0x[[A:[0-9a-f]+]] {{.*}} col:9 used a 'hlsl_constant float' cbuffer CB : register(b3, space2) { float a; } @@ -13,7 +13,7 @@ cbuffer CB : register(b3, space2) { // CHECK-NEXT:HLSLResourceClassAttr 0x[[CB:[0-9a-f]+]] {{.*}} Implicit SRV // CHECK-NEXT:HLSLResourceAttr 0x[[CB:[0-9a-f]+]] {{.*}} Implicit TBuffer // CHECK-NEXT:HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:14> "t2" "space1" -// CHECK-NEXT:VarDecl 0x[[B:[0-9a-f]+]] {{.*}} col:9 used b 'float' +// CHECK-NEXT:VarDecl 0x[[B:[0-9a-f]+]] {{.*}} col:9 used b 'hlsl_constant float' tbuffer TB : register(t2, space1) { float b; } @@ -21,9 +21,9 @@ tbuffer TB : register(t2, space1) { float foo() { // CHECK: BinaryOperator 0x{{[0-9a-f]+}} <col:10, col:14> 'float' '+' // CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-f]+}} <col:10> 'float' <LValueToRValue> -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-f]+}} <col:10> 'float' lvalue Var 0x[[A]] 'a' 'float' +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-f]+}} <col:10> 'hlsl_constant float' lvalue Var 0x[[A]] 'a' 'hlsl_constant float' // CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-f]+}} <col:14> 'float' <LValueToRValue> -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-f]+}} <col:14> 'float' lvalue Var 0x[[B]] 'b' 'float' +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-f]+}} <col:14> 'hlsl_constant float' lvalue Var 0x[[B]] 'b' 'hlsl_constant float' return a + b; } diff --git a/clang/test/CodeGenHLSL/cbuf.hlsl b/clang/test/CodeGenHLSL/cbuf.hlsl index 3f9d4514967dd2..325dfc5d8556db 100644 --- a/clang/test/CodeGenHLSL/cbuf.hlsl +++ b/clang/test/CodeGenHLSL/cbuf.hlsl @@ -2,6 +2,11 @@ // RUN: dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s +// CHECK: @a = external addrspace(2) global float, align 4 +// CHECK: @b = external addrspace(2) global double, align 8 +// CHECK: @c = external addrspace(2) global float, align 4 +// CHECK: @d = external addrspace(2) global double, align 8 + // CHECK: @[[CB:.+]] = external constant { float, double } cbuffer A : register(b0, space2) { float a; @@ -15,10 +20,10 @@ tbuffer A : register(t2, space1) { } float foo() { -// CHECK: load float, ptr @[[CB]], align 4 -// CHECK: load double, ptr getelementptr ({ float, double }, ptr @[[CB]], i32 0, i32 1), align 8 -// CHECK: load float, ptr @[[TB]], align 4 -// CHECK: load double, ptr getelementptr ({ float, double }, ptr @[[TB]], i32 0, i32 1), align 8 +// CHECK: load float, ptr addrspace(2) @a, align 4 +// CHECK: load double, ptr addrspace(2) @b, align 8 +// CHECK: load float, ptr addrspace(2) @c, align 4 +// CHECK: load double, ptr addrspace(2) @d, align 8 return a + b + c*d; } diff --git a/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl b/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl index 73dc376942dfb7..e75202c9a76169 100644 --- a/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl +++ b/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl @@ -3,6 +3,10 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s // Make sure cbuffer inside namespace works. + +// CHECK: @_ZN2n02n11aE = external addrspace(2) global float, align 4 +// CHECK: @_ZN2n01bE = external addrspace(2) global float, align 4 + // CHECK: @[[CB:.+]] = external constant { float } // CHECK: @[[TB:.+]] = external constant { float } namespace n0 { @@ -17,7 +21,7 @@ namespace n1 { } float foo() { -// CHECK: load float, ptr @[[CB]], align 4 -// CHECK: load float, ptr @[[TB]], align 4 +// CHECK: load float, ptr addrspace(2) @_ZN2n02n11aE, align 4 +// CHECK: load float, ptr addrspace(2) @_ZN2n01bE, align 4 return n0::n1::a + n0::b; } diff --git a/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl b/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl index f85bab2113170b..73ab4ebeb3eaf0 100644 --- a/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl +++ b/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl @@ -1,16 +1,18 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// CHECK-DAG: @[[CB:.+]] = external constant { float } - cbuffer A { - float a; - // CHECK-DAG:@_ZL1b = internal global float 3.000000e+00, align 4 + // CHECK: @a = external addrspace(2) global float, align 4 + float a; + // CHECK: @_ZL1b = internal global float 3.000000e+00, align 4 static float b = 3; - // CHECK:load float, ptr @[[CB]], align 4 - // CHECK:load float, ptr @_ZL1b, align 4 float foo() { return a + b; } } +// CHECK: @[[CB:.+]] = external constant { float } + +// CHECK:define {{.*}} float @_Z3foov() +// CHECK:load float, ptr addrspace(2) @a, align 4 +// CHECK:load float, ptr @_ZL1b, align 4 float bar() { return foo(); >From a89c1b998b60fd771b4ad8c73a86f954ff069018 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Tue, 21 Jan 2025 12:09:45 -0800 Subject: [PATCH 2/2] code review feedback - preserve init and use externally_initialized - update tests and add SPIRV variant - reorder switch in TypePrinter.cpp --- clang/lib/AST/TypePrinter.cpp | 4 +-- clang/lib/Basic/Targets/AMDGPU.cpp | 2 +- clang/lib/CodeGen/CGHLSLRuntime.cpp | 1 + clang/lib/Sema/SemaHLSL.cpp | 1 - ...fer.hlsl => ast-dump-comment-cbuffer.hlsl} | 30 ------------------- clang/test/CodeGenHLSL/cbuf.hlsl | 14 +++++---- clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl | 10 ++++--- .../static_global_and_function_in_cb.hlsl | 5 +++- .../SemaTemplate/address_space-dependent.cpp | 2 +- 9 files changed, 23 insertions(+), 46 deletions(-) rename clang/test/AST/HLSL/{ast-dump-comment-cbuffer-tbuffer.hlsl => ast-dump-comment-cbuffer.hlsl} (56%) diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 6cad74fef3fe33..31695374cb52b3 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2552,12 +2552,12 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) { return "__uptr __ptr32"; case LangAS::ptr64: return "__ptr64"; - case LangAS::wasm_funcref: - return "__funcref"; case LangAS::hlsl_groupshared: return "groupshared"; case LangAS::hlsl_constant: return "hlsl_constant"; + case LangAS::wasm_funcref: + return "__funcref"; default: return std::to_string(toTargetAddressSpace(AS)); } diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 824134d52ec139..d7e60efb4c27c9 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -59,6 +59,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared + llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_constant }; const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { @@ -84,7 +85,6 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_constant - }; } // namespace targets } // namespace clang diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 127bd4a7fc27f0..c7fb8786011c2b 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -128,6 +128,7 @@ void CGHLSLRuntime::addConstant(VarDecl *D, Buffer &CB) { } auto *GV = cast<GlobalVariable>(CGM.GetAddrOfGlobalVar(D)); + GV->setExternallyInitialized(true); // Add debug info for constVal. if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) if (CGM.getCodeGenOpts().getDebugInfo() >= diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 372db586f8d8ea..37ebc542482855 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -470,7 +470,6 @@ void createHostLayoutStructForBuffer(Sema &S, HLSLBufferDecl *BufDecl) { QualType NewTy = AST.getAddrSpaceQualType(VD->getType(), LangAS::hlsl_constant); VD->setType(NewTy); - VD->setInit(nullptr); } } LS->completeDefinition(); diff --git a/clang/test/AST/HLSL/ast-dump-comment-cbuffer-tbuffer.hlsl b/clang/test/AST/HLSL/ast-dump-comment-cbuffer.hlsl similarity index 56% rename from clang/test/AST/HLSL/ast-dump-comment-cbuffer-tbuffer.hlsl rename to clang/test/AST/HLSL/ast-dump-comment-cbuffer.hlsl index 3cca808ae75b63..92108072a5b94b 100644 --- a/clang/test/AST/HLSL/ast-dump-comment-cbuffer-tbuffer.hlsl +++ b/clang/test/AST/HLSL/ast-dump-comment-cbuffer.hlsl @@ -19,24 +19,6 @@ cbuffer A { int b; } -// JSON:"kind": "HLSLBufferDecl", -// JSON:"name": "B", -// JSON-NEXT:"bufferKind": "tbuffer", -// JSON:"kind": "TextComment", -// JSON:"text": " TBuffer decl." - -/// TBuffer decl. -tbuffer B { - // JSON: "kind": "VarDecl", - // JSON: "name": "c", - // JSON: "qualType": "hlsl_constant float" - float c; - // JSON: "kind": "VarDecl", - // JSON: "name": "d", - // JSON: "qualType": "hlsl_constant int" - int d; -} - // AST: HLSLBufferDecl {{.*}} line:11:9 cbuffer A // AST-NEXT: HLSLResourceClassAttr {{.*}} Implicit CBuffer // AST-NEXT: HLSLResourceAttr {{.*}} Implicit CBuffer @@ -48,15 +30,3 @@ tbuffer B { // AST-NEXT: CXXRecordDecl {{.*}} implicit class __layout.A definition // AST: FieldDecl {{.*}} a 'float' // AST-NEXT: FieldDecl {{.*}} b 'int' - -// AST-NEXT: HLSLBufferDecl {{.*}} line:29:9 tbuffer B -// AST-NEXT: HLSLResourceClassAttr {{.*}} Implicit SRV -// AST-NEXT: HLSLResourceAttr {{.*}} Implicit TBuffer -// AST-NEXT: FullComment -// AST-NEXT: ParagraphComment -// AST-NEXT: TextComment {{.*}} Text=" TBuffer decl." -// AST-NEXT: VarDecl {{.*}} c 'hlsl_constant float' -// AST-NEXT: VarDecl {{.*}} d 'hlsl_constant int' -// AST-NEXT: CXXRecordDecl {{.*}} implicit class __layout.B definition -// AST: FieldDecl {{.*}} c 'float' -// AST-NEXT: FieldDecl {{.*}} d 'int' diff --git a/clang/test/CodeGenHLSL/cbuf.hlsl b/clang/test/CodeGenHLSL/cbuf.hlsl index 325dfc5d8556db..825e7b8161a601 100644 --- a/clang/test/CodeGenHLSL/cbuf.hlsl +++ b/clang/test/CodeGenHLSL/cbuf.hlsl @@ -1,11 +1,13 @@ -// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ -// RUN: dxil-pc-shadermodel6.3-library %s \ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// CHECK: @a = external addrspace(2) global float, align 4 -// CHECK: @b = external addrspace(2) global double, align 8 -// CHECK: @c = external addrspace(2) global float, align 4 -// CHECK: @d = external addrspace(2) global double, align 8 +// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +// CHECK: @a = external addrspace(2) externally_initialized global float, align 4 +// CHECK: @b = external addrspace(2) externally_initialized global double, align 8 +// CHECK: @c = external addrspace(2) externally_initialized global float, align 4 +// CHECK: @d = external addrspace(2) externally_initialized global double, align 8 // CHECK: @[[CB:.+]] = external constant { float, double } cbuffer A : register(b0, space2) { diff --git a/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl b/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl index e75202c9a76169..13c401d4283313 100644 --- a/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl +++ b/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl @@ -1,11 +1,13 @@ -// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ -// RUN: dxil-pc-shadermodel6.3-library %s \ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s // Make sure cbuffer inside namespace works. -// CHECK: @_ZN2n02n11aE = external addrspace(2) global float, align 4 -// CHECK: @_ZN2n01bE = external addrspace(2) global float, align 4 +// CHECK: @_ZN2n02n11aE = external addrspace(2) externally_initialized global float, align 4 +// CHECK: @_ZN2n01bE = external addrspace(2) externally_initialized global float, align 4 // CHECK: @[[CB:.+]] = external constant { float } // CHECK: @[[TB:.+]] = external constant { float } diff --git a/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl b/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl index 73ab4ebeb3eaf0..25f51cce2017d2 100644 --- a/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl +++ b/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl @@ -1,8 +1,11 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s +// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s + cbuffer A { - // CHECK: @a = external addrspace(2) global float, align 4 + // CHECK: @a = external addrspace(2) externally_initialized global float, align 4 float a; // CHECK: @_ZL1b = internal global float 3.000000e+00, align 4 static float b = 3; diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp index 2ca9b8007ab418..eb8dbc69a945e2 100644 --- a/clang/test/SemaTemplate/address_space-dependent.cpp +++ b/clang/test/SemaTemplate/address_space-dependent.cpp @@ -43,7 +43,7 @@ void neg() { template <long int I> void tooBig() { - __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}} + __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388585)}} } template <long int I> _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits