Skip to content

Commit 39f17d5

Browse files
committed
Repurpose replaceExtractElementTypeOfCallUsages to replace InsertValueInsts as well
- Renamed replaceExtractElementTypeOfCallUsages to replaceAggregateTypeOfCallUsages and made it replace uses of InsertValueInsts in addition to ExtractValueInst - Added a test case to UAddc_errors.ll to ensure there are no other uses, and emit an error if so - Added a test case to UAddc.ll to test the replacement of InsertValueInsts - Removed the check on the number of indices, as this is error case is already handled. (It would be invalid LLVM IR.) This also makes the function more generally applicable in case another function would like to use it
1 parent 28b7eb8 commit 39f17d5

File tree

3 files changed

+40
-16
lines changed

3 files changed

+40
-16
lines changed

llvm/lib/Target/DirectX/DXILOpLowering.cpp

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -359,21 +359,17 @@ class OpLowerer {
359359
return lowerToBindAndAnnotateHandle(F);
360360
}
361361

362-
Error replaceExtractElementTypeOfCallUsages(CallInst *Intrin, CallInst *Op) {
362+
Error replaceAggregateTypeOfCallUsages(CallInst *Intrin, CallInst *Op) {
363363
for (Use &U : make_early_inc_range(Intrin->uses())) {
364364
if (auto *EVI = dyn_cast<ExtractValueInst>(U.getUser())) {
365-
366-
if (EVI->getNumIndices() != 1)
367-
return createStringError(
368-
std::errc::invalid_argument,
369-
(std::string(Intrin->getOpcodeName()) + " has only 2 elements")
370-
.c_str());
371365
EVI->setOperand(0, Op);
366+
} else if (auto *IVI = dyn_cast<InsertValueInst>(U.getUser())) {
367+
IVI->setOperand(0, Op);
372368
} else {
373-
return make_error<StringError>((std::string(Intrin->getOpcodeName()) +
374-
" use is not ExtractValueInst")
375-
.c_str(),
376-
inconvertibleErrorCode());
369+
return make_error<StringError>(
370+
(Intrin->getCalledFunction()->getName() +
371+
" use is not a ExtractValueInst or InsertValueInst"),
372+
inconvertibleErrorCode());
377373
}
378374
}
379375

@@ -824,7 +820,7 @@ class OpLowerer {
824820
F, OpCode::SplitDouble,
825821
OpBuilder.getSplitDoubleType(M.getContext()),
826822
[&](CallInst *CI, CallInst *Op) {
827-
return replaceExtractElementTypeOfCallUsages(CI, Op);
823+
return replaceAggregateTypeOfCallUsages(CI, Op);
828824
});
829825
break;
830826
// TODO: this can be removed when
@@ -833,7 +829,7 @@ class OpLowerer {
833829
HasErrors |= replaceFunctionWithNamedStructOp(
834830
F, OpCode::UAddc, OpBuilder.getBinaryWithCarryType(M.getContext()),
835831
[&](CallInst *CI, CallInst *Op) {
836-
return replaceExtractElementTypeOfCallUsages(CI, Op);
832+
return replaceAggregateTypeOfCallUsages(CI, Op);
837833
});
838834
break;
839835
case Intrinsic::ctpop:

llvm/test/CodeGen/DirectX/UAddc.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@ define noundef i32 @test_UAddc(i32 noundef %a, i32 noundef %b) {
2020
ret i32 %result
2121
}
2222

23+
24+
define noundef i32 @test_UAddc_insert(i32 noundef %a, i32 noundef %b) {
25+
; CHECK-LABEL: define noundef i32 @test_UAddc_insert(
26+
; CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) {
27+
; CHECK-NEXT: [[UAddc:%.*]] = call %dx.types.i32c @dx.op.binaryWithCarryOrBorrow.i32(i32 44, i32 [[A]], i32 [[B]])
28+
; CHECK-NEXT: insertvalue %dx.types.i32c [[UAddc]], i32 [[A]], 0
29+
; CHECK-NEXT: [[Result:%.*]] = extractvalue %dx.types.i32c [[UAddc]], 0
30+
; CHECK-NEXT: ret i32 [[Result]]
31+
;
32+
%uaddc = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
33+
insertvalue { i32, i1 } %uaddc, i32 %a, 0
34+
%result = extractvalue { i32, i1 } %uaddc, 0
35+
ret i32 %result
36+
}
37+
2338
declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
2439
; CHECK: declare %dx.types.i32c @dx.op.binaryWithCarryOrBorrow.i32(i32, i32, i32)
2540

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s
1+
; We use llc for this test so that we don't abort after the first error.
2+
; RUN: not llc %s -o /dev/null 2>&1 | FileCheck %s
3+
4+
target triple = "dxil-pc-shadermodel6.3-library"
25

36
; DXIL operation UAddc only supports i32. Other integer types are unsupported.
4-
; CHECK: in function uaddc_i16
7+
; CHECK: error:
8+
; CHECK-SAME: in function uaddc_i16
59
; CHECK-SAME: Cannot create UAddc operation: Invalid overload type
610

7-
define noundef i16 @uaddc_i16(i16 noundef %a, i16 noundef %b) {
11+
define noundef i16 @uaddc_i16(i16 noundef %a, i16 noundef %b) "hlsl.export" {
812
%uaddc = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 %a, i16 %b)
913
%carry = extractvalue { i16, i1 } %uaddc, 1
1014
%sum = extractvalue { i16, i1 } %uaddc, 0
@@ -13,5 +17,14 @@ define noundef i16 @uaddc_i16(i16 noundef %a, i16 noundef %b) {
1317
ret i16 %result
1418
}
1519

20+
; CHECK: error:
21+
; CHECK-SAME: in function uaddc_return
22+
; CHECK-SAME: llvm.uadd.with.overflow.i32 use is not a ExtractValueInst or InsertValueInst
23+
24+
define noundef { i32, i1 } @uaddc_return(i32 noundef %a, i32 noundef %b) "hlsl.export" {
25+
%uaddc = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
26+
ret { i32, i1 } %uaddc
27+
}
28+
1629
declare { i16, i1 } @llvm.uadd.with.overflow.i16(i16, i16)
1730

0 commit comments

Comments
 (0)