Skip to content

Commit 7475996

Browse files
committed
Make AddUint64 use llvm.uadd.with.overflow.v2i32 for uint4 args
This commit depends on changes to be merged from PR llvm#126815
1 parent e784664 commit 7475996

File tree

3 files changed

+115
-77
lines changed

3 files changed

+115
-77
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19461,31 +19461,50 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
1946119461
4)) &&
1946219462
"input vectors must have 2 or 4 elements each");
1946319463

19464-
llvm::Value *Result = PoisonValue::get(OpA->getType());
1946519464
uint64_t NumElements =
1946619465
E->getArg(0)->getType()->castAs<VectorType>()->getNumElements();
19467-
for (uint64_t i = 0; i < NumElements / 2; ++i) {
19468-
19469-
// Obtain low and high words of inputs A and B
19470-
llvm::Value *LowA = Builder.CreateExtractElement(OpA, 2 * i + 0);
19471-
llvm::Value *HighA = Builder.CreateExtractElement(OpA, 2 * i + 1);
19472-
llvm::Value *LowB = Builder.CreateExtractElement(OpB, 2 * i + 0);
19473-
llvm::Value *HighB = Builder.CreateExtractElement(OpB, 2 * i + 1);
19474-
19475-
// Use an uadd_with_overflow to compute the sum of low words and obtain a
19476-
// carry value
19477-
llvm::Value *Carry;
19478-
llvm::Value *LowSum = EmitOverflowIntrinsic(
19479-
*this, llvm::Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
19480-
llvm::Value *ZExtCarry = Builder.CreateZExt(Carry, HighA->getType());
19481-
19482-
// Sum the high words and the carry
19483-
llvm::Value *HighSum = Builder.CreateAdd(HighA, HighB);
19484-
llvm::Value *HighSumPlusCarry = Builder.CreateAdd(HighSum, ZExtCarry);
19485-
19486-
// Insert the low and high word sums into the result vector
19487-
Result = Builder.CreateInsertElement(Result, LowSum, 2 * i + 0);
19488-
Result = Builder.CreateInsertElement(Result, HighSumPlusCarry, 2 * i + 1,
19466+
19467+
llvm::Value *Result = PoisonValue::get(OpA->getType());
19468+
llvm::Value *LowA;
19469+
llvm::Value *HighA;
19470+
llvm::Value *LowB;
19471+
llvm::Value *HighB;
19472+
19473+
// Obtain low and high words of inputs A and B
19474+
if (NumElements == 2) {
19475+
LowA = Builder.CreateExtractElement(OpA, (uint64_t)0, "LowA");
19476+
HighA = Builder.CreateExtractElement(OpA, (uint64_t)1, "HighA");
19477+
LowB = Builder.CreateExtractElement(OpB, (uint64_t)0, "LowB");
19478+
HighB = Builder.CreateExtractElement(OpB, (uint64_t)1, "HighB");
19479+
} else {
19480+
LowA = Builder.CreateShuffleVector(OpA, ArrayRef<int>{0, 2}, "LowA");
19481+
HighA = Builder.CreateShuffleVector(OpA, ArrayRef<int>{1, 3}, "HighA");
19482+
LowB = Builder.CreateShuffleVector(OpB, ArrayRef<int>{0, 2}, "LowB");
19483+
HighB = Builder.CreateShuffleVector(OpB, ArrayRef<int>{1, 3}, "HighB");
19484+
}
19485+
19486+
// Use an uadd_with_overflow to compute the sum of low words and obtain a
19487+
// carry value
19488+
llvm::Value *Carry;
19489+
llvm::Value *LowSum = EmitOverflowIntrinsic(
19490+
*this, llvm::Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
19491+
llvm::Value *ZExtCarry =
19492+
Builder.CreateZExt(Carry, HighA->getType(), "CarryZExt");
19493+
19494+
// Sum the high words and the carry
19495+
llvm::Value *HighSum = Builder.CreateAdd(HighA, HighB, "HighSum");
19496+
llvm::Value *HighSumPlusCarry =
19497+
Builder.CreateAdd(HighSum, ZExtCarry, "HighSumPlusCarry");
19498+
19499+
// Insert the low and high word sums into the result vector
19500+
if (NumElements == 2) {
19501+
Result = Builder.CreateInsertElement(Result, LowSum, (uint64_t)0,
19502+
"hlsl.AddUint64.upto0");
19503+
Result = Builder.CreateInsertElement(Result, HighSumPlusCarry,
19504+
(uint64_t)1, "hlsl.AddUint64");
19505+
} else { /* NumElements == 4 */
19506+
Result = Builder.CreateShuffleVector(LowSum, HighSumPlusCarry,
19507+
ArrayRef<int>{0, 2, 1, 3},
1948919508
"hlsl.AddUint64");
1949019509
}
1949119510
return Result;

clang/test/CodeGenHLSL/builtins/AddUint64.hlsl

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@
1111
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <2 x i32>, align 8
1212
// CHECK-NEXT: store <2 x i32> [[A]], ptr [[A_ADDR]], align 8
1313
// CHECK-NEXT: store <2 x i32> [[B]], ptr [[B_ADDR]], align 8
14-
// CHECK-NEXT: [[A_LOAD:%.*]] = load <2 x i32>, ptr [[A_ADDR]], align 8
15-
// CHECK-NEXT: [[B_LOAD:%.*]] = load <2 x i32>, ptr [[B_ADDR]], align 8
16-
// CHECK-NEXT: [[LowA:%.*]] = extractelement <2 x i32> [[A_LOAD]], i64 0
17-
// CHECK-NEXT: [[HighA:%.*]] = extractelement <2 x i32> [[A_LOAD]], i64 1
18-
// CHECK-NEXT: [[LowB:%.*]] = extractelement <2 x i32> [[B_LOAD]], i64 0
19-
// CHECK-NEXT: [[HighB:%.*]] = extractelement <2 x i32> [[B_LOAD]], i64 1
20-
// CHECK-NEXT: [[UAddc:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[LowA]], i32 [[LowB]])
21-
// CHECK-NEXT: [[Carry:%.*]] = extractvalue { i32, i1 } [[UAddc]], 1
22-
// CHECK-NEXT: [[LowSum:%.*]] = extractvalue { i32, i1 } [[UAddc]], 0
23-
// CHECK-NEXT: [[CarryZExt:%.*]] = zext i1 [[Carry]] to i32
24-
// CHECK-NEXT: [[HighSum:%.*]] = add i32 [[HighA]], [[HighB]]
25-
// CHECK-NEXT: [[HighSumPlusCarry:%.*]] = add i32 [[HighSum]], [[CarryZExt]]
26-
// CHECK-NEXT: [[HLSL_ADDUINT64_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[LowSum]], i64 0
27-
// CHECK-NEXT: [[HLSL_ADDUINT64:%.*]] = insertelement <2 x i32> [[HLSL_ADDUINT64_UPTO0]], i32 [[HighSumPlusCarry]], i64 1
14+
// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[A_ADDR]], align 8
15+
// CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32>, ptr [[B_ADDR]], align 8
16+
// CHECK-NEXT: [[LOWA:%.*]] = extractelement <2 x i32> [[TMP0]], i64 0
17+
// CHECK-NEXT: [[HIGHA:%.*]] = extractelement <2 x i32> [[TMP0]], i64 1
18+
// CHECK-NEXT: [[LOWB:%.*]] = extractelement <2 x i32> [[TMP1]], i64 0
19+
// CHECK-NEXT: [[HIGHB:%.*]] = extractelement <2 x i32> [[TMP1]], i64 1
20+
// CHECK-NEXT: [[TMP2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[LOWA]], i32 [[LOWB]])
21+
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
22+
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
23+
// CHECK-NEXT: [[CARRYZEXT:%.*]] = zext i1 [[TMP3]] to i32
24+
// CHECK-NEXT: [[HIGHSUM:%.*]] = add i32 [[HIGHA]], [[HIGHB]]
25+
// CHECK-NEXT: [[HIGHSUMPLUSCARRY:%.*]] = add i32 [[HIGHSUM]], [[CARRYZEXT]]
26+
// CHECK-NEXT: [[HLSL_ADDUINT64_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[TMP4]], i64 0
27+
// CHECK-NEXT: [[HLSL_ADDUINT64:%.*]] = insertelement <2 x i32> [[HLSL_ADDUINT64_UPTO0]], i32 [[HIGHSUMPLUSCARRY]], i64 1
2828
// CHECK-NEXT: ret <2 x i32> [[HLSL_ADDUINT64]]
2929
//
3030
uint2 test_AddUint64_uint2(uint2 a, uint2 b) {
@@ -38,32 +38,19 @@ uint2 test_AddUint64_uint2(uint2 a, uint2 b) {
3838
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <4 x i32>, align 16
3939
// CHECK-NEXT: store <4 x i32> [[A]], ptr [[A_ADDR]], align 16
4040
// CHECK-NEXT: store <4 x i32> [[B]], ptr [[B_ADDR]], align 16
41-
// CHECK-NEXT: [[A_LOAD:%.*]] = load <4 x i32>, ptr [[A_ADDR]], align 16
42-
// CHECK-NEXT: [[B_LOAD:%.*]] = load <4 x i32>, ptr [[B_ADDR]], align 16
43-
// CHECK-NEXT: [[LowA:%.*]] = extractelement <4 x i32> [[A_LOAD]], i64 0
44-
// CHECK-NEXT: [[HighA:%.*]] = extractelement <4 x i32> [[A_LOAD]], i64 1
45-
// CHECK-NEXT: [[LowB:%.*]] = extractelement <4 x i32> [[B_LOAD]], i64 0
46-
// CHECK-NEXT: [[HighB:%.*]] = extractelement <4 x i32> [[B_LOAD]], i64 1
47-
// CHECK-NEXT: [[UAddc:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[LowA]], i32 [[LowB]])
48-
// CHECK-NEXT: [[Carry:%.*]] = extractvalue { i32, i1 } [[UAddc]], 1
49-
// CHECK-NEXT: [[LowSum:%.*]] = extractvalue { i32, i1 } [[UAddc]], 0
50-
// CHECK-NEXT: [[CarryZExt:%.*]] = zext i1 [[Carry]] to i32
51-
// CHECK-NEXT: [[HighSum:%.*]] = add i32 [[HighA]], [[HighB]]
52-
// CHECK-NEXT: [[HighSumPlusCarry:%.*]] = add i32 [[HighSum]], [[CarryZExt]]
53-
// CHECK-NEXT: [[HLSL_ADDUINT64_UPTO0:%.*]] = insertelement <4 x i32> poison, i32 [[LowSum]], i64 0
54-
// CHECK-NEXT: [[HLSL_ADDUINT64_UPTO1:%.*]] = insertelement <4 x i32> [[HLSL_ADDUINT64_UPTO0]], i32 [[HighSumPlusCarry]], i64 1
55-
// CHECK-NEXT: [[LowA1:%.*]] = extractelement <4 x i32> [[A_LOAD]], i64 2
56-
// CHECK-NEXT: [[HighA1:%.*]] = extractelement <4 x i32> [[A_LOAD]], i64 3
57-
// CHECK-NEXT: [[LowB1:%.*]] = extractelement <4 x i32> [[B_LOAD]], i64 2
58-
// CHECK-NEXT: [[HighB1:%.*]] = extractelement <4 x i32> [[B_LOAD]], i64 3
59-
// CHECK-NEXT: [[UAddc1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[LowA1]], i32 [[LowB1]])
60-
// CHECK-NEXT: [[Carry1:%.*]] = extractvalue { i32, i1 } [[UAddc1]], 1
61-
// CHECK-NEXT: [[LowSum1:%.*]] = extractvalue { i32, i1 } [[UAddc1]], 0
62-
// CHECK-NEXT: [[CarryZExt1:%.*]] = zext i1 [[Carry1]] to i32
63-
// CHECK-NEXT: [[HighSum1:%.*]] = add i32 [[HighA1]], [[HighB1]]
64-
// CHECK-NEXT: [[HighSumPlusCarry1:%.*]] = add i32 [[HighSum1]], [[CarryZExt1]]
65-
// CHECK-NEXT: [[HLSL_ADDUINT64_UPTO2:%.*]] = insertelement <4 x i32> [[HLSL_ADDUINT64_UPTO1]], i32 [[LowSum1]], i64 2
66-
// CHECK-NEXT: [[HLSL_ADDUINT64:%.*]] = insertelement <4 x i32> [[HLSL_ADDUINT64_UPTO2]], i32 [[HighSumPlusCarry1]], i64 3
41+
// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[A_ADDR]], align 16
42+
// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[B_ADDR]], align 16
43+
// CHECK-NEXT: [[LOWA:%.*]] = shufflevector <4 x i32> [[TMP0]], <4 x i32> poison, <2 x i32> <i32 0, i32 2>
44+
// CHECK-NEXT: [[HIGHA:%.*]] = shufflevector <4 x i32> [[TMP0]], <4 x i32> poison, <2 x i32> <i32 1, i32 3>
45+
// CHECK-NEXT: [[LOWB:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <2 x i32> <i32 0, i32 2>
46+
// CHECK-NEXT: [[HIGHB:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <2 x i32> <i32 1, i32 3>
47+
// CHECK-NEXT: [[TMP2:%.*]] = call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> [[LOWA]], <2 x i32> [[LOWB]])
48+
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <2 x i32>, <2 x i1> } [[TMP2]], 1
49+
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { <2 x i32>, <2 x i1> } [[TMP2]], 0
50+
// CHECK-NEXT: [[CARRYZEXT:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32>
51+
// CHECK-NEXT: [[HIGHSUM:%.*]] = add <2 x i32> [[HIGHA]], [[HIGHB]]
52+
// CHECK-NEXT: [[HIGHSUMPLUSCARRY:%.*]] = add <2 x i32> [[HIGHSUM]], [[CARRYZEXT]]
53+
// CHECK-NEXT: [[HLSL_ADDUINT64:%.*]] = shufflevector <2 x i32> [[TMP4]], <2 x i32> [[HIGHSUMPLUSCARRY]], <4 x i32> <i32 0, i32 2, i32 1, i32 3>
6754
// CHECK-NEXT: ret <4 x i32> [[HLSL_ADDUINT64]]
6855
//
6956
uint4 test_AddUint64_uint4(uint4 a, uint4 b) {

llvm/test/CodeGen/DirectX/UAddc.ll

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -scalarizer -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
23

34
; CHECK: %dx.types.i32c = type { i32, i1 }
45

56
define noundef i32 @test_UAddc(i32 noundef %a, i32 noundef %b) {
67
; CHECK-LABEL: define noundef i32 @test_UAddc(
78
; CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) {
8-
; CHECK-NEXT: [[UAddc:%.*]] = call %dx.types.i32c @dx.op.binaryWithCarryOrBorrow.i32(i32 44, i32 [[A]], i32 [[B]])
9-
; CHECK-NEXT: [[Carry:%.*]] = extractvalue %dx.types.i32c [[UAddc]], 1
10-
; CHECK-NEXT: [[Sum:%.*]] = extractvalue %dx.types.i32c [[UAddc]], 0
11-
; CHECK-NEXT: [[CarryZExt:%.*]] = zext i1 [[Carry]] to i32
12-
; CHECK-NEXT: [[Result:%.*]] = add i32 [[Sum]], [[CarryZExt]]
13-
; CHECK-NEXT: ret i32 [[Result]]
14-
;
9+
; CHECK-NEXT: [[UADDC1:%.*]] = call [[DX_TYPES_I32C:%.*]] @[[DX_OP_BINARYWITHCARRYORBORROW_I32:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](i32 44, i32 [[A]], i32 [[B]]) #[[ATTR0:[0-9]+]]
10+
; CHECK-NEXT: [[CARRY:%.*]] = extractvalue [[DX_TYPES_I32C]] [[UADDC1]], 1
11+
; CHECK-NEXT: [[SUM:%.*]] = extractvalue [[DX_TYPES_I32C]] [[UADDC1]], 0
12+
; CHECK-NEXT: [[CARRY_ZEXT:%.*]] = zext i1 [[CARRY]] to i32
13+
; CHECK-NEXT: [[RESULT:%.*]] = add i32 [[SUM]], [[CARRY_ZEXT]]
14+
; CHECK-NEXT: ret i32 [[RESULT]]
15+
;
1516
%uaddc = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
1617
%carry = extractvalue { i32, i1 } %uaddc, 1
1718
%sum = extractvalue { i32, i1 } %uaddc, 0
@@ -20,21 +21,52 @@ define noundef i32 @test_UAddc(i32 noundef %a, i32 noundef %b) {
2021
ret i32 %result
2122
}
2223

24+
define noundef <2 x i32> @test_UAddc_vec2(<2 x i32> noundef %a, <2 x i32> noundef %b) {
25+
; CHECK-LABEL: define noundef <2 x i32> @test_UAddc_vec2(
26+
; CHECK-SAME: <2 x i32> noundef [[A:%.*]], <2 x i32> noundef [[B:%.*]]) {
27+
; CHECK-NEXT: [[A_I0:%.*]] = extractelement <2 x i32> [[A]], i64 0
28+
; CHECK-NEXT: [[B_I0:%.*]] = extractelement <2 x i32> [[B]], i64 0
29+
; CHECK-NEXT: [[UADDC_I09:%.*]] = call [[DX_TYPES_I32C:%.*]] @[[DX_OP_BINARYWITHCARRYORBORROW_I32]](i32 44, i32 [[A_I0]], i32 [[B_I0]]) #[[ATTR0]]
30+
; CHECK-NEXT: [[A_I1:%.*]] = extractelement <2 x i32> [[A]], i64 1
31+
; CHECK-NEXT: [[B_I1:%.*]] = extractelement <2 x i32> [[B]], i64 1
32+
; CHECK-NEXT: [[UADDC_I18:%.*]] = call [[DX_TYPES_I32C]] @[[DX_OP_BINARYWITHCARRYORBORROW_I32]](i32 44, i32 [[A_I1]], i32 [[B_I1]]) #[[ATTR0]]
33+
; CHECK-NEXT: [[CARRY_ELEM1:%.*]] = extractvalue [[DX_TYPES_I32C]] [[UADDC_I09]], 1
34+
; CHECK-NEXT: [[CARRY_ELEM11:%.*]] = extractvalue [[DX_TYPES_I32C]] [[UADDC_I18]], 1
35+
; CHECK-NEXT: [[CARRY_UPTO0:%.*]] = insertelement <2 x i1> poison, i1 [[CARRY_ELEM1]], i64 0
36+
; CHECK-NEXT: [[CARRY:%.*]] = insertelement <2 x i1> [[CARRY_UPTO0]], i1 [[CARRY_ELEM11]], i64 1
37+
; CHECK-NEXT: [[CARRY_I0:%.*]] = extractelement <2 x i1> [[CARRY]], i64 0
38+
; CHECK-NEXT: [[CARRY_I1:%.*]] = extractelement <2 x i1> [[CARRY]], i64 1
39+
; CHECK-NEXT: [[SUM_ELEM0:%.*]] = extractvalue [[DX_TYPES_I32C]] [[UADDC_I09]], 0
40+
; CHECK-NEXT: [[SUM_ELEM02:%.*]] = extractvalue [[DX_TYPES_I32C]] [[UADDC_I18]], 0
41+
; CHECK-NEXT: [[CARRY_ZEXT_I0:%.*]] = zext i1 [[CARRY_I0]] to i32
42+
; CHECK-NEXT: [[CARRY_ZEXT_I1:%.*]] = zext i1 [[CARRY_I1]] to i32
43+
; CHECK-NEXT: [[RESULT_I0:%.*]] = add i32 [[SUM_ELEM0]], [[CARRY_ZEXT_I0]]
44+
; CHECK-NEXT: [[RESULT_I1:%.*]] = add i32 [[SUM_ELEM02]], [[CARRY_ZEXT_I1]]
45+
; CHECK-NEXT: [[RESULT_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[RESULT_I0]], i64 0
46+
; CHECK-NEXT: [[RESULT:%.*]] = insertelement <2 x i32> [[RESULT_UPTO0]], i32 [[RESULT_I1]], i64 1
47+
; CHECK-NEXT: ret <2 x i32> [[RESULT]]
48+
;
49+
%uaddc = call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> %a, <2 x i32> %b)
50+
%carry = extractvalue { <2 x i32>, <2 x i1> } %uaddc, 1
51+
%sum = extractvalue { <2 x i32>, <2 x i1> } %uaddc, 0
52+
%carry_zext = zext <2 x i1> %carry to <2 x i32>
53+
%result = add <2 x i32> %sum, %carry_zext
54+
ret <2 x i32> %result
55+
}
2356

2457
define noundef i32 @test_UAddc_insert(i32 noundef %a, i32 noundef %b) {
2558
; CHECK-LABEL: define noundef i32 @test_UAddc_insert(
2659
; 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-
;
60+
; CHECK-NEXT: [[UADDC1:%.*]] = call [[DX_TYPES_I32C:%.*]] @[[DX_OP_BINARYWITHCARRYORBORROW_I32]](i32 44, i32 [[A]], i32 [[B]]) #[[ATTR0]]
61+
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[DX_TYPES_I32C]] [[UADDC1]], i32 [[A]], 0
62+
; CHECK-NEXT: [[RESULT:%.*]] = extractvalue [[DX_TYPES_I32C]] [[UADDC1]], 0
63+
; CHECK-NEXT: ret i32 [[RESULT]]
64+
;
3265
%uaddc = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
3366
insertvalue { i32, i1 } %uaddc, i32 %a, 0
3467
%result = extractvalue { i32, i1 } %uaddc, 0
3568
ret i32 %result
3669
}
3770

3871
declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
39-
; CHECK: declare %dx.types.i32c @dx.op.binaryWithCarryOrBorrow.i32(i32, i32, i32)
4072

0 commit comments

Comments
 (0)