Skip to content

Implement the AddUint64 HLSL Function #99205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
8 tasks
Tracked by #99235
farzonl opened this issue Jul 16, 2024 · 4 comments · Fixed by #127137
Closed
8 tasks
Tracked by #99235

Implement the AddUint64 HLSL Function #99205

farzonl opened this issue Jul 16, 2024 · 4 comments · Fixed by #127137
Assignees
Labels
backend:DirectX bot:HLSL clang:codegen IR generation bugs: mangling, exceptions, etc. clang:frontend Language frontend issues, e.g. anything involving "Sema" HLSL HLSL Language Support metabug Issue to collect references to a group of similar or related issues.

Comments

@farzonl
Copy link
Member

farzonl commented Jul 16, 2024

  • Implement AddUint64 via use of the __builtin_addc clang builtin in hlsl_intrinsics.h
  • (optional) If custom sema needed add sema checks for AddUint64 to CheckHLSLBuiltinFunctionCall in SemaHLSL.cpp
  • Try to use llvm::Intrinsic::uadd_with_overflow codegen for AddUint64 in CGBuiltin.cpp
  • Add codegen tests to clang/test/CodeGenHLSL/builtins/AddUint64.hlsl
  • Add sema tests to clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl
  • Create the DXILOpMapping of int_uadd_with_overflow to 44 in DXIL.td
  • Create the AddUint64.ll and AddUint64_errors.ll tests in llvm/test/CodeGen/DirectX/
  • Legalize int_uadd_with_overflow for SPIRV.

DirectX

DXIL Opcode DXIL OpName Shader Model Shader Stages
44 UAddc 6.0 ()

SPIR-V

There is no support for AddUint64 when targeting SPIR-V.

Test Case(s)

Example 1

//dxc AddUint64_test.hlsl -T lib_6_8 -enable-16bit-types -O0

export uint4 fn(uint4 p1, uint4 p2) {
    return AddUint64(p1, p2);
}

HLSL:

Syntax

uint<2> AddUint64(uint<2> a, uint<2> b);
uint<4> AddUint64(uint<4> a, uint<4> b);

Type Description

Name Template Type Component Type Size
ret vector uint 2
a vector uint 2
b vector uint 2

Type Description

Name Template Type Component Type Size
ret vector uint 4
a vector uint 4
b vector uint 4

Minimum Shader Model

This function is supported in the following shader models.

Shader Model Supported
Shader Model 6 and higher shader models yes

Shader Stages

See also

@farzonl farzonl added backend:DirectX bot:HLSL HLSL HLSL Language Support metabug Issue to collect references to a group of similar or related issues. labels Jul 16, 2024
@damyanp damyanp moved this to Ready in HLSL Support Oct 30, 2024
@damyanp damyanp moved this from Ready to Planning in HLSL Support Oct 30, 2024
@tex3d
Copy link
Contributor

tex3d commented Dec 3, 2024

The point of this intrinsic is to implement a uint64_t add without requiring the native 64-bit feature.

This takes (one or two) pairs (low,high) of uint32 values and results in pairs (low,high) of uint32 values. It uses the UAddc (unsigned add with carry) to preserve the extra bit which it uses with zext and ordinary add instructions to implement a full uint64 add operation, resulting in the (low,high) part pairs. This intrinsic requires either a 2 or 4-length vector (so diagnostics need to be implemented for this).

; add low words with carry:
%13 = call %dx.types.i32c @dx.op.binaryWithCarryOrBorrow.i32(i32 44i32 %5i32 %1)  ; UAddc(a,b)
%14 = extractvalue %dx.types.i32c %130 ; i32 low word result
%15 = extractvalue %dx.types.i32c %131 ; i1 carry bit
%16 = zext i1 %15 to i32 ; extend carry bit to i32
%17 = add i32 %6%2 ; add high words
%18 = add i32 %17%16 ; add carry bit for high word result

SPIR-V has a OpIAddCarry operation which can be used in exactly the same way.
According to SPIR-V Spec: "Result is the unsigned integer addition of Operand 1 and Operand 2, including its carry."

LLVM already has an intrinsic llvm.uadd.with.overflow that we can use for IRGen, then we can just lower that to the respective DXIL or SPIR-V op in the backend.

@farzonl farzonl moved this from Designing to Planning in HLSL Support Jan 13, 2025
@davidcook-msft davidcook-msft moved this from Planning to Ready in HLSL Support Jan 14, 2025
@Icohedron
Copy link
Contributor

I will work on this issue.

@damyanp damyanp moved this from Ready to Active in HLSL Support Jan 27, 2025
@damyanp damyanp moved this from Active to Needs Review in HLSL Support Feb 3, 2025
@github-project-automation github-project-automation bot moved this from Needs Review to Closed in HLSL Support Mar 6, 2025
@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:codegen IR generation bugs: mangling, exceptions, etc. labels Mar 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 6, 2025

@llvm/issue-subscribers-clang-frontend

Author: Farzon Lotfi (farzonl)

- [ ] Implement `AddUint64` via use of the `__builtin_addc` clang builtin in `hlsl_intrinsics.h` - [ ] (optional) If custom sema needed add sema checks for `AddUint64` to `CheckHLSLBuiltinFunctionCall` in `SemaHLSL.cpp` - [ ] Try to use `llvm::Intrinsic::uadd_with_overflow` codegen for `AddUint64` in `CGBuiltin.cpp` - [ ] Add codegen tests to `clang/test/CodeGenHLSL/builtins/AddUint64.hlsl` - [ ] Add sema tests to `clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl` - [ ] Create the `DXILOpMapping` of `int_uadd_with_overflow` to `44` in `DXIL.td` - [ ] Create the `AddUint64.ll` and `AddUint64_errors.ll` tests in `llvm/test/CodeGen/DirectX/` - [ ] Legalize `int_uadd_with_overflow` for SPIRV.

DirectX

DXIL Opcode DXIL OpName Shader Model Shader Stages
44 UAddc 6.0 ()

SPIR-V

There is no support for AddUint64 when targeting SPIR-V.

Test Case(s)

Example 1

//dxc AddUint64_test.hlsl -T lib_6_8 -enable-16bit-types -O0

export uint4 fn(uint4 p1, uint4 p2) {
    return AddUint64(p1, p2);
}

HLSL:

Syntax

uint&lt;2&gt; AddUint64(uint&lt;2&gt; a, uint&lt;2&gt; b);
uint&lt;4&gt; AddUint64(uint&lt;4&gt; a, uint&lt;4&gt; b);

Type Description

Name Template Type Component Type Size
ret vector uint 2
a vector uint 2
b vector uint 2

Type Description

Name Template Type Component Type Size
ret vector uint 4
a vector uint 4
b vector uint 4

Minimum Shader Model

This function is supported in the following shader models.

Shader Model Supported
Shader Model 6 and higher shader models yes

Shader Stages

See also

@llvmbot
Copy link
Member

llvmbot commented Mar 6, 2025

@llvm/issue-subscribers-clang-codegen

Author: Farzon Lotfi (farzonl)

- [ ] Implement `AddUint64` via use of the `__builtin_addc` clang builtin in `hlsl_intrinsics.h` - [ ] (optional) If custom sema needed add sema checks for `AddUint64` to `CheckHLSLBuiltinFunctionCall` in `SemaHLSL.cpp` - [ ] Try to use `llvm::Intrinsic::uadd_with_overflow` codegen for `AddUint64` in `CGBuiltin.cpp` - [ ] Add codegen tests to `clang/test/CodeGenHLSL/builtins/AddUint64.hlsl` - [ ] Add sema tests to `clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl` - [ ] Create the `DXILOpMapping` of `int_uadd_with_overflow` to `44` in `DXIL.td` - [ ] Create the `AddUint64.ll` and `AddUint64_errors.ll` tests in `llvm/test/CodeGen/DirectX/` - [ ] Legalize `int_uadd_with_overflow` for SPIRV.

DirectX

DXIL Opcode DXIL OpName Shader Model Shader Stages
44 UAddc 6.0 ()

SPIR-V

There is no support for AddUint64 when targeting SPIR-V.

Test Case(s)

Example 1

//dxc AddUint64_test.hlsl -T lib_6_8 -enable-16bit-types -O0

export uint4 fn(uint4 p1, uint4 p2) {
    return AddUint64(p1, p2);
}

HLSL:

Syntax

uint&lt;2&gt; AddUint64(uint&lt;2&gt; a, uint&lt;2&gt; b);
uint&lt;4&gt; AddUint64(uint&lt;4&gt; a, uint&lt;4&gt; b);

Type Description

Name Template Type Component Type Size
ret vector uint 2
a vector uint 2
b vector uint 2

Type Description

Name Template Type Component Type Size
ret vector uint 4
a vector uint 4
b vector uint 4

Minimum Shader Model

This function is supported in the following shader models.

Shader Model Supported
Shader Model 6 and higher shader models yes

Shader Stages

See also

jph-13 pushed a commit to jph-13/llvm-project that referenced this issue Mar 21, 2025
…L op (llvm#127137)

Fixes llvm#99205.

- Implements the HLSL intrinsic `AddUint64` used to perform unsigned
64-bit integer addition by using pairs of unsigned 32-bit integers
instead of native 64-bit types
- The LLVM intrinsic `uadd_with_overflow` is used in the implementation
of `AddUint64` in `CGBuiltin.cpp`
- The DXIL op `UAddc` was defined in `DXIL.td`, and a lowering of the
LLVM intrinsic `uadd_with_overflow` to the `UAddc` DXIL op was
implemented in `DXILOpLowering.cpp`

Notes:
- `__builtin_addc` was not able to be used to implement `AddUint64` in
`hlsl_intrinsics.h` because its `CarryOut` argument is a pointer, and
pointers are not supported in HLSL
- A lowering of the LLVM intrinsic `uadd_with_overflow` to SPIR-V
[already
exists](https://github.com/llvm/llvm-project/blob/main/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll)
- When lowering the LLVM intrinsic `uadd_with_overflow` to the `UAddc`
DXIL op, the anonymous struct type `{ i32, i1 }` is replaced with a
named struct type `%dx.types.i32c`. This aspect of the implementation
may be changed when issue llvm#113192 gets addressed
- Fixes issues mentioned in the comments on the original PR llvm#125319

---------

Co-authored-by: Finn Plummer <[email protected]>
Co-authored-by: Farzon Lotfi <[email protected]>
Co-authored-by: Chris B <[email protected]>
Co-authored-by: Justin Bogner <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:DirectX bot:HLSL clang:codegen IR generation bugs: mangling, exceptions, etc. clang:frontend Language frontend issues, e.g. anything involving "Sema" HLSL HLSL Language Support metabug Issue to collect references to a group of similar or related issues.
Projects
Status: Closed
Development

Successfully merging a pull request may close this issue.

5 participants