From 609a82a8c957f8a2178373f3630345944ce023f6 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Thu, 27 Feb 2025 17:47:11 +0000 Subject: [PATCH 1/5] Set function-level flag Int64Ops in DXIL Shader Flags Analysis --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 12 ++++++++ .../DirectX/ShaderFlags/double-extensions.ll | 11 +++---- .../CodeGen/DirectX/ShaderFlags/int64ops.ll | 30 +++++++++++++++++++ .../propagate-function-flags-test.ll | 11 +++---- 4 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/ShaderFlags/int64ops.ll diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index e1cf516758663..7740baa9b904d 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -99,6 +99,18 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, } } + if (!CSF.Int64Ops) + CSF.Int64Ops = I.getType()->isIntegerTy() && I.getType()->getScalarSizeInBits() == 64; + + if (!CSF.Int64Ops) { + for (const Value *Op : I.operands()) { + if (Op->getType()->isIntegerTy() && Op->getType()->getScalarSizeInBits() == 64) { + CSF.Int64Ops = true; + break; + } + } + } + if (auto *II = dyn_cast(&I)) { switch (II->getIntrinsicID()) { default: diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/double-extensions.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/double-extensions.ll index d6df67626be5a..dd8ea5f5b1aec 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/double-extensions.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/double-extensions.ll @@ -3,16 +3,17 @@ target triple = "dxil-pc-shadermodel6.7-library" ; CHECK: ; Combined Shader Flags for Module -; CHECK-NEXT: ; Shader Flags Value: 0x00000044 +; CHECK-NEXT: ; Shader Flags Value: 0x00100044 ; CHECK: ; Note: shader requires additional functionality: ; CHECK-NEXT: ; Double-precision floating point ; CHECK-NEXT: ; Double-precision extensions for 11.1 +; CHECK-NEXT: ; 64-Bit integer ; CHECK-NEXT: ; Note: extra DXIL module flags: ; CHECK-NEXT: ; ; CHECK-NEXT: ; Shader Flags for Module Functions -;CHECK: ; Function top_level : 0x00000044 +;CHECK: ; Function top_level : 0x00100044 define double @top_level() #0 { %r = call double @test_uitofp_i64(i64 5) ret double %r @@ -25,13 +26,13 @@ define double @test_fdiv_double(double %a, double %b) #0 { ret double %res } -; CHECK: ; Function test_uitofp_i64 : 0x00000044 +; CHECK: ; Function test_uitofp_i64 : 0x00100044 define double @test_uitofp_i64(i64 %a) #0 { %r = uitofp i64 %a to double ret double %r } -; CHECK: ; Function test_sitofp_i64 : 0x00000044 +; CHECK: ; Function test_sitofp_i64 : 0x00100044 define double @test_sitofp_i64(i64 %a) #0 { %r = sitofp i64 %a to double ret double %r @@ -43,7 +44,7 @@ define i32 @test_fptoui_i32(double %a) #0 { ret i32 %r } -; CHECK: ; Function test_fptosi_i64 : 0x00000044 +; CHECK: ; Function test_fptosi_i64 : 0x00100044 define i64 @test_fptosi_i64(double %a) #0 { %r = fptosi double %a to i64 ret i64 %r diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/int64ops.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/int64ops.ll new file mode 100644 index 0000000000000..320c775e7130e --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/int64ops.ll @@ -0,0 +1,30 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s +; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC + +target triple = "dxil-pc-shadermodel6.7-library" + +;CHECK: ; Combined Shader Flags for Module +;CHECK-NEXT: ; Shader Flags Value: 0x00100000 +;CHECK-NEXT: ; +;CHECK-NEXT: ; Note: shader requires additional functionality: +;CHECK-NEXT: ; 64-Bit integer +;CHECK-NEXT: ; Note: extra DXIL module flags: +;CHECK-NEXT: ; +;CHECK-NEXT: ; Shader Flags for Module Functions +;CHECK-NEXT: ; Function add : 0x00100000 + +define i64 @add(i64 %a, i64 %b) #0 { + %sum = add i64 %a, %b + ret i64 %sum +} + +attributes #0 = { convergent norecurse nounwind "hlsl.export"} + +; DXC: - Name: SFI0 +; DXC-NEXT: Size: 8 +; DXC-NEXT: Flags: +; DXC-NOT: {{[A-Za-z]+: +true}} +; DXC: Int64Ops: true +; DXC-NOT: {{[A-Za-z]+: +true}} +; DXC: NextUnusedBit: false +; DXC: ... diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/propagate-function-flags-test.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/propagate-function-flags-test.ll index e7a2cf4d5b20f..8dee842e85e44 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/propagate-function-flags-test.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/propagate-function-flags-test.ll @@ -3,11 +3,12 @@ target triple = "dxil-pc-shadermodel6.7-library" ; CHECK: ; Combined Shader Flags for Module -; CHECK-NEXT: ; Shader Flags Value: 0x00000044 +; CHECK-NEXT: ; Shader Flags Value: 0x00100044 ; CHECK-NEXT: ; ; CHECK-NEXT: ; Note: shader requires additional functionality: ; CHECK-NEXT: ; Double-precision floating point ; CHECK-NEXT: ; Double-precision extensions for 11.1 +; CHECK-NEXT: ; 64-Bit integer ; CHECK-NEXT: ; Note: extra DXIL module flags: ; CHECK-NEXT: ; ; CHECK-NEXT: ; Shader Flags for Module Functions @@ -55,13 +56,13 @@ define double @call_get_uitofp_flag(i32 noundef %0) local_unnamed_addr #0 { ret double %2 } -; CHECK: ; Function call_get_fptoui_flag : 0x00000044 +; CHECK: ; Function call_get_fptoui_flag : 0x00100044 define double @call_get_fptoui_flag(double noundef %0) local_unnamed_addr #0 { %2 = tail call double @get_fptoui_flag(double noundef %0) ret double %2 } -; CHECK: ; Function get_fptoui_flag : 0x00000044 +; CHECK: ; Function get_fptoui_flag : 0x00100044 define double @get_fptoui_flag(double noundef %0) local_unnamed_addr #0 { %2 = fcmp ugt double %0, 5.000000e+00 br i1 %2, label %6, label %3 @@ -81,7 +82,7 @@ define double @get_fptoui_flag(double noundef %0) local_unnamed_addr #0 { ret double %10 } -; CHECK: ; Function get_sitofp_uitofp_flag : 0x00000044 +; CHECK: ; Function get_sitofp_uitofp_flag : 0x00100044 define double @get_sitofp_uitofp_flag(i64 noundef %0) local_unnamed_addr #0 { %2 = icmp ult i64 %0, 6 br i1 %2, label %3, label %7 @@ -154,7 +155,7 @@ define double @get_all_doubles_flags(i32 noundef %0) local_unnamed_addr #0 { ret double %4 } -; CHECK: ; Function main : 0x00000044 +; CHECK: ; Function main : 0x00100044 define i32 @main() local_unnamed_addr #0 { %1 = tail call double @get_fptoui_flag(double noundef 1.000000e+00) %2 = tail call double @get_sitofp_fdiv_flag(i32 noundef 4) From 7edbef530bb52702f65702efad9416f8ba35c71b Mon Sep 17 00:00:00 2001 From: Icohedron Date: Thu, 27 Feb 2025 17:53:46 +0000 Subject: [PATCH 2/5] Apply clang-format --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index 7740baa9b904d..3aad769c0ea5f 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -100,11 +100,13 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, } if (!CSF.Int64Ops) - CSF.Int64Ops = I.getType()->isIntegerTy() && I.getType()->getScalarSizeInBits() == 64; + CSF.Int64Ops = + I.getType()->isIntegerTy() && I.getType()->getScalarSizeInBits() == 64; if (!CSF.Int64Ops) { for (const Value *Op : I.operands()) { - if (Op->getType()->isIntegerTy() && Op->getType()->getScalarSizeInBits() == 64) { + if (Op->getType()->isIntegerTy() && + Op->getType()->getScalarSizeInBits() == 64) { CSF.Int64Ops = true; break; } From 4f09a48043e7f83d66dafc43a21203f3772d4795 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Fri, 28 Feb 2025 20:55:34 +0000 Subject: [PATCH 3/5] Use isIntegerTy(64) to check for 64-bit integer type --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index 3aad769c0ea5f..29d1e8e24de1a 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -100,13 +100,11 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, } if (!CSF.Int64Ops) - CSF.Int64Ops = - I.getType()->isIntegerTy() && I.getType()->getScalarSizeInBits() == 64; + CSF.Int64Ops = I.getType()->isIntegerTy(64); if (!CSF.Int64Ops) { for (const Value *Op : I.operands()) { - if (Op->getType()->isIntegerTy() && - Op->getType()->getScalarSizeInBits() == 64) { + if (Op->getType()->isIntegerTy(64)) { CSF.Int64Ops = true; break; } From 77379d6fbb7e5eb8aaafc880aae0b7050c949342 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Tue, 4 Mar 2025 14:01:45 -0800 Subject: [PATCH 4/5] Ignore i64 ConstantInt indices from ExtractElement and InsertElement instructions that fit within 32 bits --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index babf495220393..eea56a26ca37c 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -118,6 +118,24 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, if (!CSF.Int64Ops) { for (const Value *Op : I.operands()) { if (Op->getType()->isIntegerTy(64)) { + + // Special-case handling for ConstantInt indices of ExtractElement and + // InsertElement instructions (likely inserted by the Scalarization + // pass). As long as the constant indices fit within 32 bits, we do not + // consider them to count as 64-bit integer usage. + switch (I.getOpcode()) { + case Instruction::ExtractElement: + case Instruction::InsertElement: + if (Op == I.getOperand(I.getNumOperands() - 1)) { // Index operand + if (isa(Op)) { + const ConstantInt *CI = cast(Op); + // The constant index must fit within 32 bits + if (CI->getZExtValue() <= UINT32_MAX) + continue; + } + } + } + CSF.Int64Ops = true; break; } From 5f084f0ef5b5d81716df9eff89f6fc19b5fbbb90 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Mon, 17 Mar 2025 18:43:05 +0000 Subject: [PATCH 5/5] Revert "Ignore i64 ConstantInt indices from ExtractElement and InsertElement instructions that fit within 32 bits" This reverts commit 77379d6fbb7e5eb8aaafc880aae0b7050c949342. --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index eea56a26ca37c..babf495220393 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -118,24 +118,6 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, if (!CSF.Int64Ops) { for (const Value *Op : I.operands()) { if (Op->getType()->isIntegerTy(64)) { - - // Special-case handling for ConstantInt indices of ExtractElement and - // InsertElement instructions (likely inserted by the Scalarization - // pass). As long as the constant indices fit within 32 bits, we do not - // consider them to count as 64-bit integer usage. - switch (I.getOpcode()) { - case Instruction::ExtractElement: - case Instruction::InsertElement: - if (Op == I.getOperand(I.getNumOperands() - 1)) { // Index operand - if (isa(Op)) { - const ConstantInt *CI = cast(Op); - // The constant index must fit within 32 bits - if (CI->getZExtValue() <= UINT32_MAX) - continue; - } - } - } - CSF.Int64Ops = true; break; }