xref: /llvm-project/llvm/test/Transforms/CodeGenPrepare/AArch64/overflow-intrinsics.ll (revision f1ec0d12bb0843f0deab83ef2b5cf1339cbc4f0b)
1106ae108SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2*f1ec0d12SNick Anderson; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -S < %s | FileCheck %s
3*f1ec0d12SNick Anderson; RUN: opt -enable-debugify -passes='require<profile-summary>,function(codegenprepare)' -S < %s 2>&1 | FileCheck %s -check-prefix=DEBUG
4106ae108SFlorian Hahn
5106ae108SFlorian Hahn; Subset of tests from llvm/tests/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
6106ae108SFlorian Hahn; to test shouldFormOverflowOp on SPARC, where it is not profitable to create
7106ae108SFlorian Hahn; overflow intrinsics if the math part is not used.
8106ae108SFlorian Hahn
9106ae108SFlorian Hahntarget triple = "arm64-apple-iphoneos"
10106ae108SFlorian Hahn
11106ae108SFlorian Hahndefine i64 @uaddo1_overflow_used(i64 %a, i64 %b) nounwind ssp {
12106ae108SFlorian Hahn; CHECK-LABEL: @uaddo1_overflow_used(
13106ae108SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])
14106ae108SFlorian Hahn; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
15106ae108SFlorian Hahn; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
16106ae108SFlorian Hahn; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
17106ae108SFlorian Hahn; CHECK-NEXT:    ret i64 [[Q]]
18106ae108SFlorian Hahn;
19106ae108SFlorian Hahn  %add = add i64 %b, %a
20106ae108SFlorian Hahn  %cmp = icmp ult i64 %add, %a
21106ae108SFlorian Hahn  %Q = select i1 %cmp, i64 %b, i64 42
22106ae108SFlorian Hahn  ret i64 %Q
23106ae108SFlorian Hahn}
24106ae108SFlorian Hahn
25d9e51e75SMatt Arsenaultdefine i64 @uaddo1_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {
26106ae108SFlorian Hahn; CHECK-LABEL: @uaddo1_math_overflow_used(
27106ae108SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])
28106ae108SFlorian Hahn; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
29106ae108SFlorian Hahn; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
30106ae108SFlorian Hahn; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
31d9e51e75SMatt Arsenault; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]]
32106ae108SFlorian Hahn; CHECK-NEXT:    ret i64 [[Q]]
33106ae108SFlorian Hahn;
34106ae108SFlorian Hahn  %add = add i64 %b, %a
35106ae108SFlorian Hahn  %cmp = icmp ult i64 %add, %a
36106ae108SFlorian Hahn  %Q = select i1 %cmp, i64 %b, i64 42
37d9e51e75SMatt Arsenault  store i64 %add, ptr %res
38106ae108SFlorian Hahn  ret i64 %Q
39106ae108SFlorian Hahn}
40106ae108SFlorian Hahn
41106ae108SFlorian Hahndefine i64 @uaddo2_overflow_used(i64 %a, i64 %b) nounwind ssp {
42106ae108SFlorian Hahn; CHECK-LABEL: @uaddo2_overflow_used(
43106ae108SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])
44106ae108SFlorian Hahn; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
45106ae108SFlorian Hahn; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
46106ae108SFlorian Hahn; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
47106ae108SFlorian Hahn; CHECK-NEXT:    ret i64 [[Q]]
48106ae108SFlorian Hahn;
49106ae108SFlorian Hahn  %add = add i64 %b, %a
50106ae108SFlorian Hahn  %cmp = icmp ult i64 %add, %b
51106ae108SFlorian Hahn  %Q = select i1 %cmp, i64 %b, i64 42
52106ae108SFlorian Hahn  ret i64 %Q
53106ae108SFlorian Hahn}
54106ae108SFlorian Hahn
55d9e51e75SMatt Arsenaultdefine i64 @uaddo2_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {
56106ae108SFlorian Hahn; CHECK-LABEL: @uaddo2_math_overflow_used(
57106ae108SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])
58106ae108SFlorian Hahn; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
59106ae108SFlorian Hahn; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
60106ae108SFlorian Hahn; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
61d9e51e75SMatt Arsenault; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]]
62106ae108SFlorian Hahn; CHECK-NEXT:    ret i64 [[Q]]
63106ae108SFlorian Hahn;
64106ae108SFlorian Hahn  %add = add i64 %b, %a
65106ae108SFlorian Hahn  %cmp = icmp ult i64 %add, %b
66106ae108SFlorian Hahn  %Q = select i1 %cmp, i64 %b, i64 42
67d9e51e75SMatt Arsenault  store i64 %add, ptr %res
68106ae108SFlorian Hahn  ret i64 %Q
69106ae108SFlorian Hahn}
70106ae108SFlorian Hahn
71106ae108SFlorian Hahndefine i64 @uaddo3_overflow_used(i64 %a, i64 %b) nounwind ssp {
72106ae108SFlorian Hahn; CHECK-LABEL: @uaddo3_overflow_used(
73106ae108SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])
74106ae108SFlorian Hahn; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
75106ae108SFlorian Hahn; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
76106ae108SFlorian Hahn; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
77106ae108SFlorian Hahn; CHECK-NEXT:    ret i64 [[Q]]
78106ae108SFlorian Hahn;
79106ae108SFlorian Hahn  %add = add i64 %b, %a
80106ae108SFlorian Hahn  %cmp = icmp ugt i64 %b, %add
81106ae108SFlorian Hahn  %Q = select i1 %cmp, i64 %b, i64 42
82106ae108SFlorian Hahn  ret i64 %Q
83106ae108SFlorian Hahn}
84106ae108SFlorian Hahn
85d9e51e75SMatt Arsenaultdefine i64 @uaddo3_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {
86106ae108SFlorian Hahn; CHECK-LABEL: @uaddo3_math_overflow_used(
87106ae108SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])
88106ae108SFlorian Hahn; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
89106ae108SFlorian Hahn; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
90106ae108SFlorian Hahn; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
91d9e51e75SMatt Arsenault; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]]
92106ae108SFlorian Hahn; CHECK-NEXT:    ret i64 [[Q]]
93106ae108SFlorian Hahn;
94106ae108SFlorian Hahn  %add = add i64 %b, %a
95106ae108SFlorian Hahn  %cmp = icmp ugt i64 %b, %add
96106ae108SFlorian Hahn  %Q = select i1 %cmp, i64 %b, i64 42
97d9e51e75SMatt Arsenault  store i64 %add, ptr %res
98106ae108SFlorian Hahn  ret i64 %Q
99106ae108SFlorian Hahn}
100106ae108SFlorian Hahn
1017cbf7103SFlorian Hahn; Instcombine folds (a + b <u a)  to (a ^ -1 <u b). Make sure we match this
1027cbf7103SFlorian Hahn; pattern as well.
1037cbf7103SFlorian Hahndefine i64 @uaddo6_xor(i64 %a, i64 %b) {
1047cbf7103SFlorian Hahn; CHECK-LABEL: @uaddo6_xor(
1057769030bSFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]])
1067769030bSFlorian Hahn; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
1077769030bSFlorian Hahn; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
1087cbf7103SFlorian Hahn; CHECK-NEXT:    ret i64 [[Q]]
1097cbf7103SFlorian Hahn;
1107cbf7103SFlorian Hahn  %x = xor i64 %a, -1
1117cbf7103SFlorian Hahn  %cmp = icmp ult i64 %x, %b
1127cbf7103SFlorian Hahn  %Q = select i1 %cmp, i64 %b, i64 42
1137cbf7103SFlorian Hahn  ret i64 %Q
1147cbf7103SFlorian Hahn}
1157cbf7103SFlorian Hahn
1167cbf7103SFlorian Hahndefine i64 @uaddo6_xor_commuted(i64 %a, i64 %b) {
1177cbf7103SFlorian Hahn; CHECK-LABEL: @uaddo6_xor_commuted(
1187769030bSFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]])
1197769030bSFlorian Hahn; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
1207769030bSFlorian Hahn; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
1217cbf7103SFlorian Hahn; CHECK-NEXT:    ret i64 [[Q]]
1227cbf7103SFlorian Hahn;
1237769030bSFlorian Hahn  %x = xor i64 %a, -1
1247769030bSFlorian Hahn  %cmp = icmp ugt i64 %b, %x
1257cbf7103SFlorian Hahn  %Q = select i1 %cmp, i64 %b, i64 42
1267cbf7103SFlorian Hahn  ret i64 %Q
1277cbf7103SFlorian Hahn}
1287cbf7103SFlorian Hahn
1297cbf7103SFlorian Hahndeclare void @use(i64)
1307cbf7103SFlorian Hahn
1317cbf7103SFlorian Hahndefine i64 @uaddo6_xor_multi_use(i64 %a, i64 %b) {
1327cbf7103SFlorian Hahn; CHECK-LABEL: @uaddo6_xor_multi_use(
1337cbf7103SFlorian Hahn; CHECK-NEXT:    [[X:%.*]] = xor i64 -1, [[A:%.*]]
1347cbf7103SFlorian Hahn; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[X]], [[B:%.*]]
1357cbf7103SFlorian Hahn; CHECK-NEXT:    [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42
1367cbf7103SFlorian Hahn; CHECK-NEXT:    call void @use(i64 [[X]])
1377cbf7103SFlorian Hahn; CHECK-NEXT:    ret i64 [[Q]]
1387cbf7103SFlorian Hahn;
1397cbf7103SFlorian Hahn  %x = xor i64 -1, %a
1407cbf7103SFlorian Hahn  %cmp = icmp ult i64 %x, %b
1417cbf7103SFlorian Hahn  %Q = select i1 %cmp, i64 %b, i64 42
1427cbf7103SFlorian Hahn  call void @use(i64 %x)
1437cbf7103SFlorian Hahn  ret i64 %Q
1447cbf7103SFlorian Hahn}
1457cbf7103SFlorian Hahn
146d9e51e75SMatt Arsenaultdefine i1 @usubo_ult_i64_overflow_used(i64 %x, i64 %y, ptr %p) {
147106ae108SFlorian Hahn; CHECK-LABEL: @usubo_ult_i64_overflow_used(
148106ae108SFlorian Hahn; CHECK-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]]
149106ae108SFlorian Hahn; CHECK-NEXT:    [[OV:%.*]] = icmp ult i64 [[X]], [[Y]]
150106ae108SFlorian Hahn; CHECK-NEXT:    ret i1 [[OV]]
151106ae108SFlorian Hahn;
152106ae108SFlorian Hahn  %s = sub i64 %x, %y
153106ae108SFlorian Hahn  %ov = icmp ult i64 %x, %y
154106ae108SFlorian Hahn  ret i1 %ov
155106ae108SFlorian Hahn}
156106ae108SFlorian Hahn
157d9e51e75SMatt Arsenaultdefine i1 @usubo_ult_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) {
158106ae108SFlorian Hahn; CHECK-LABEL: @usubo_ult_i64_math_overflow_used(
159106ae108SFlorian Hahn; CHECK-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]]
160d9e51e75SMatt Arsenault; CHECK-NEXT:    store i64 [[S]], ptr [[P:%.*]]
161106ae108SFlorian Hahn; CHECK-NEXT:    [[OV:%.*]] = icmp ult i64 [[X]], [[Y]]
162106ae108SFlorian Hahn; CHECK-NEXT:    ret i1 [[OV]]
163106ae108SFlorian Hahn;
164106ae108SFlorian Hahn  %s = sub i64 %x, %y
165d9e51e75SMatt Arsenault  store i64 %s, ptr %p
166106ae108SFlorian Hahn  %ov = icmp ult i64 %x, %y
167106ae108SFlorian Hahn  ret i1 %ov
168106ae108SFlorian Hahn}
169106ae108SFlorian Hahn
170*f1ec0d12SNick Anderson; Check that every instruction inserted by -passes='require<profile-summary>,function(codegenprepare)' has a debug location.
171106ae108SFlorian Hahn; DEBUG: CheckModuleDebugify: PASS
172