1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt < %s -passes=newgvn -S | FileCheck %s
7 define i64 @test1(i64 %a, i64 %b) nounwind ssp {
8 ; CHECK-LABEL: define i64 @test1(
9 ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0:[0-9]+]] {
11 ; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A]], i64 [[B]])
12 ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
13 ; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
14 ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
15 ; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
16 ; CHECK-NEXT: [[UADD_0:%.*]] = extractvalue [[TMP0]] [[TMP4]], 0
17 ; CHECK-NEXT: [[ADD2:%.*]] = add i64 [[TMP1]], [[UADD_0]]
18 ; CHECK-NEXT: ret i64 [[ADD2]]
21 %uadd = tail call %0 @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)
22 %uadd.0 = extractvalue %0 %uadd, 0
23 %add1 = add i64 %a, %b
24 %add2 = add i64 %add1, %uadd.0
29 define i64 @test2(i64 %a, i64 %b) nounwind ssp {
30 ; CHECK-LABEL: define i64 @test2(
31 ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
33 ; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[A]], i64 [[B]])
34 ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
35 ; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
36 ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
37 ; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
38 ; CHECK-NEXT: [[USUB_0:%.*]] = extractvalue [[TMP0]] [[TMP4]], 0
39 ; CHECK-NEXT: [[ADD2:%.*]] = add i64 [[TMP1]], [[USUB_0]]
40 ; CHECK-NEXT: ret i64 [[ADD2]]
43 %usub = tail call %0 @llvm.usub.with.overflow.i64(i64 %a, i64 %b)
44 %usub.0 = extractvalue %0 %usub, 0
45 %sub1 = sub i64 %a, %b
46 %add2 = add i64 %sub1, %usub.0
51 define i64 @test3(i64 %a, i64 %b) nounwind ssp {
52 ; CHECK-LABEL: define i64 @test3(
53 ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
55 ; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[A]], i64 [[B]])
56 ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
57 ; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
58 ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
59 ; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
60 ; CHECK-NEXT: [[UMUL_0:%.*]] = extractvalue [[TMP0]] [[TMP4]], 0
61 ; CHECK-NEXT: [[ADD2:%.*]] = add i64 [[TMP1]], [[UMUL_0]]
62 ; CHECK-NEXT: ret i64 [[ADD2]]
65 %umul = tail call %0 @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
66 %umul.0 = extractvalue %0 %umul, 0
67 %mul1 = mul i64 %a, %b
68 %add2 = add i64 %mul1, %umul.0
73 define i64 @test4(i64 %a, i64 %b) nounwind ssp {
74 ; CHECK-LABEL: define i64 @test4(
75 ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
77 ; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 [[A]], i64 [[B]])
78 ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
79 ; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
80 ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
81 ; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
82 ; CHECK-NEXT: [[SADD_0:%.*]] = extractvalue [[TMP0]] [[TMP4]], 0
83 ; CHECK-NEXT: [[ADD2:%.*]] = add i64 [[TMP1]], [[SADD_0]]
84 ; CHECK-NEXT: ret i64 [[ADD2]]
87 %sadd = tail call %0 @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
88 %sadd.0 = extractvalue %0 %sadd, 0
89 %add1 = add i64 %a, %b
90 %add2 = add i64 %add1, %sadd.0
95 define i64 @test5(i64 %a, i64 %b) nounwind ssp {
96 ; CHECK-LABEL: define i64 @test5(
97 ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
99 ; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 [[A]], i64 [[B]])
100 ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
101 ; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
102 ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
103 ; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
104 ; CHECK-NEXT: [[SSUB_0:%.*]] = extractvalue [[TMP0]] [[TMP4]], 0
105 ; CHECK-NEXT: [[ADD2:%.*]] = add i64 [[TMP1]], [[SSUB_0]]
106 ; CHECK-NEXT: ret i64 [[ADD2]]
109 %ssub = tail call %0 @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
110 %ssub.0 = extractvalue %0 %ssub, 0
111 %sub1 = sub i64 %a, %b
112 %add2 = add i64 %sub1, %ssub.0
117 define i64 @test6(i64 %a, i64 %b) nounwind ssp {
118 ; CHECK-LABEL: define i64 @test6(
119 ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
121 ; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 [[A]], i64 [[B]])
122 ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
123 ; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
124 ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
125 ; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
126 ; CHECK-NEXT: [[SMUL_0:%.*]] = extractvalue [[TMP0]] [[TMP4]], 0
127 ; CHECK-NEXT: [[ADD2:%.*]] = add i64 [[TMP1]], [[SMUL_0]]
128 ; CHECK-NEXT: ret i64 [[ADD2]]
131 %smul = tail call %0 @llvm.smul.with.overflow.i64(i64 %a, i64 %b)
132 %smul.0 = extractvalue %0 %smul, 0
133 %mul1 = mul i64 %a, %b
134 %add2 = add i64 %mul1, %smul.0
139 declare void @exit(i32) noreturn
140 declare %0 @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
141 declare %0 @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
142 declare %0 @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
143 declare %0 @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
144 declare %0 @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
145 declare %0 @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone