[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)
Deric Cheung via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 4 16:56:34 PST 2025
================
@@ -359,18 +359,21 @@ class OpLowerer {
return lowerToBindAndAnnotateHandle(F);
}
- Error replaceSplitDoubleCallUsages(CallInst *Intrin, CallInst *Op) {
+ Error replaceExtractElementTypeOfCallUsages(CallInst *Intrin, CallInst *Op) {
for (Use &U : make_early_inc_range(Intrin->uses())) {
if (auto *EVI = dyn_cast<ExtractValueInst>(U.getUser())) {
if (EVI->getNumIndices() != 1)
- return createStringError(std::errc::invalid_argument,
- "Splitdouble has only 2 elements");
+ return createStringError(
----------------
Icohedron wrote:
The new `replaceFunctionWithNamedStructOp` would look like this
```c++
[[nodiscard]] bool replaceFunctionWithNamedStructOp(Function &F,
dxil::OpCode DXILOp,
Type *NewRetTy) {
bool IsVectorArgExpansion = isVectorArgExpansion(F);
return replaceFunction(F, [&](CallInst *CI) -> Error {
SmallVector<Value *> Args;
OpBuilder.getIRB().SetInsertPoint(CI);
if (IsVectorArgExpansion) {
SmallVector<Value *> NewArgs = argVectorFlatten(CI, OpBuilder.getIRB());
Args.append(NewArgs.begin(), NewArgs.end());
} else
Args.append(CI->arg_begin(), CI->arg_end());
Expected<CallInst *> OpCall =
OpBuilder.tryCreateOp(DXILOp, Args, CI->getName(), NewRetTy);
if (Error E = OpCall.takeError())
return E;
for (Use &U : make_early_inc_range(CI->uses())) {
U.set(*OpCall);
}
CI->eraseFromParent();
return Error::success();
});
}
```
It works. All aggregate operations (`extractvalue`, `insertvalue`) get replaced correctly.
The only issue is if a function returns the result directly:
```c++
define noundef { i32, i1 } @test_UAddc2(i32 noundef %a, i32 noundef %b) {
; CHECK-LABEL: define noundef %dx.types.i32c @test_UAddc2(
; CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) {
; CHECK-NEXT: [[UAddc:%.*]] = call %dx.types.i32c @dx.op.binaryWithCarryOrBorrow.i32(i32 44, i32 [[A]], i32 [[B]])
; CHECK-NEXT: ret %dx.types.i32c [[Result]]
;
%uaddc = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
ret { i32, i1 } %uaddc
}
```
It results in an error that reads:
```
opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library /home/icohedron/workspace/feature-uaddc/llvm/test/CodeGen/DirectX/UAddc.ll
Function return type does not match operand type of return inst!
ret %dx.types.i32c %uaddc1
{ i32, i1 }in function test_UAddc2
LLVM ERROR: Broken function found, compilation aborted!
...
```
https://github.com/llvm/llvm-project/pull/125319
More information about the cfe-commits
mailing list