xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/ssub-with-overflow.ll (revision 8e6d481f3b7da224f8dd28a06fa91602e824db18)
161bb2e4eSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
261bb2e4eSFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
361bb2e4eSFlorian Hahn
461bb2e4eSFlorian Hahndeclare { i8, i1 } @llvm.ssub.with.overflow.i8(i8, i8)
561bb2e4eSFlorian Hahn
661bb2e4eSFlorian Hahndefine i8 @ssub_no_overflow_due_to_or_conds(i8 %a, i8 %b) {
761bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_or_conds(
861bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
961bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sle i8 [[B:%.*]], [[A:%.*]]
1061bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i8 [[A]], 0
1161bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OR_COND:%.*]] = or i1 [[C_2]], [[C_1]]
1261bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_COND]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
1361bb2e4eSFlorian Hahn; CHECK:       math:
14*8e6d481fSFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = sub i8 [[B]], [[A]]
15*8e6d481fSFlorian Hahn; CHECK-NEXT:    br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
1661bb2e4eSFlorian Hahn; CHECK:       exit.ok:
17*8e6d481fSFlorian Hahn; CHECK-NEXT:    ret i8 [[TMP0]]
1861bb2e4eSFlorian Hahn; CHECK:       exit.fail:
1961bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
2061bb2e4eSFlorian Hahn;
2161bb2e4eSFlorian Hahnentry:
2261bb2e4eSFlorian Hahn  %c.1 = icmp sle i8 %b, %a
2361bb2e4eSFlorian Hahn  %c.2 = icmp slt i8 %a, 0
2461bb2e4eSFlorian Hahn  %or.cond = or i1 %c.2, %c.1
2561bb2e4eSFlorian Hahn  br i1 %or.cond, label %exit.fail, label %math
2661bb2e4eSFlorian Hahn
2761bb2e4eSFlorian Hahnmath:
2861bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
2961bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
3061bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
3161bb2e4eSFlorian Hahn
3261bb2e4eSFlorian Hahnexit.ok:
3361bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
3461bb2e4eSFlorian Hahn  ret i8 %res
3561bb2e4eSFlorian Hahn
3661bb2e4eSFlorian Hahnexit.fail:
3761bb2e4eSFlorian Hahn  ret i8 0
3861bb2e4eSFlorian Hahn}
3961bb2e4eSFlorian Hahn
40301fe084SFlorian Hahndeclare void @use_res({ i8, i1 })
41301fe084SFlorian Hahn
42301fe084SFlorian Hahndefine i8 @ssub_no_overflow_due_to_or_conds_result_used(i8 %a, i8 %b) {
43301fe084SFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_or_conds_result_used(
44301fe084SFlorian Hahn; CHECK-NEXT:  entry:
45301fe084SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sle i8 [[B:%.*]], [[A:%.*]]
46301fe084SFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i8 [[A]], 0
47301fe084SFlorian Hahn; CHECK-NEXT:    [[OR_COND:%.*]] = or i1 [[C_2]], [[C_1]]
48301fe084SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_COND]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
49301fe084SFlorian Hahn; CHECK:       math:
50*8e6d481fSFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = sub i8 [[B]], [[A]]
51301fe084SFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
52301fe084SFlorian Hahn; CHECK-NEXT:    call void @use_res({ i8, i1 } [[OP]])
53*8e6d481fSFlorian Hahn; CHECK-NEXT:    br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
54301fe084SFlorian Hahn; CHECK:       exit.ok:
55*8e6d481fSFlorian Hahn; CHECK-NEXT:    ret i8 [[TMP0]]
56301fe084SFlorian Hahn; CHECK:       exit.fail:
57301fe084SFlorian Hahn; CHECK-NEXT:    ret i8 0
58301fe084SFlorian Hahn;
59301fe084SFlorian Hahnentry:
60301fe084SFlorian Hahn  %c.1 = icmp sle i8 %b, %a
61301fe084SFlorian Hahn  %c.2 = icmp slt i8 %a, 0
62301fe084SFlorian Hahn  %or.cond = or i1 %c.2, %c.1
63301fe084SFlorian Hahn  br i1 %or.cond, label %exit.fail, label %math
64301fe084SFlorian Hahn
65301fe084SFlorian Hahnmath:
66301fe084SFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
67301fe084SFlorian Hahn  call void @use_res({ i8, i1 } %op)
68301fe084SFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
69301fe084SFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
70301fe084SFlorian Hahn
71301fe084SFlorian Hahnexit.ok:
72301fe084SFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
73301fe084SFlorian Hahn  ret i8 %res
74301fe084SFlorian Hahn
75301fe084SFlorian Hahnexit.fail:
76301fe084SFlorian Hahn  ret i8 0
77301fe084SFlorian Hahn}
78301fe084SFlorian Hahn
7961bb2e4eSFlorian Hahndefine i8 @ssub_no_overflow_due_to_and_conds(i8 %a, i8 %b) {
8061bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_and_conds(
8161bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
8261bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]]
8361bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[A]], 0
8461bb2e4eSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
8561bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
8661bb2e4eSFlorian Hahn; CHECK:       math:
87*8e6d481fSFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = sub i8 [[B]], [[A]]
88*8e6d481fSFlorian Hahn; CHECK-NEXT:    br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
8961bb2e4eSFlorian Hahn; CHECK:       exit.ok:
90*8e6d481fSFlorian Hahn; CHECK-NEXT:    ret i8 [[TMP0]]
9161bb2e4eSFlorian Hahn; CHECK:       exit.fail:
9261bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
9361bb2e4eSFlorian Hahn;
9461bb2e4eSFlorian Hahnentry:
9561bb2e4eSFlorian Hahn  %c.1 = icmp sge i8 %b, %a
9661bb2e4eSFlorian Hahn  %c.2 = icmp sge i8 %a, 0
9761bb2e4eSFlorian Hahn  %and = and i1 %c.2, %c.1
9861bb2e4eSFlorian Hahn  br i1 %and, label %math, label %exit.fail
9961bb2e4eSFlorian Hahn
10061bb2e4eSFlorian Hahnmath:
10161bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
10261bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
10361bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
10461bb2e4eSFlorian Hahn
10561bb2e4eSFlorian Hahnexit.ok:
10661bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
10761bb2e4eSFlorian Hahn  ret i8 %res
10861bb2e4eSFlorian Hahn
10961bb2e4eSFlorian Hahnexit.fail:
11061bb2e4eSFlorian Hahn  ret i8 0
11161bb2e4eSFlorian Hahn}
11261bb2e4eSFlorian Hahn
113301fe084SFlorian Hahndefine i8 @ssub_no_overflow_due_to_and_conds_sub_result_not_used(i8 %a, i8 %b) {
114301fe084SFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_and_conds_sub_result_not_used(
115301fe084SFlorian Hahn; CHECK-NEXT:  entry:
116301fe084SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]]
117301fe084SFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[A]], 0
118301fe084SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
119301fe084SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
120301fe084SFlorian Hahn; CHECK:       math:
121*8e6d481fSFlorian Hahn; CHECK-NEXT:    br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
122301fe084SFlorian Hahn; CHECK:       exit.ok:
123301fe084SFlorian Hahn; CHECK-NEXT:    ret i8 20
124301fe084SFlorian Hahn; CHECK:       exit.fail:
125301fe084SFlorian Hahn; CHECK-NEXT:    ret i8 0
126301fe084SFlorian Hahn;
127301fe084SFlorian Hahnentry:
128301fe084SFlorian Hahn  %c.1 = icmp sge i8 %b, %a
129301fe084SFlorian Hahn  %c.2 = icmp sge i8 %a, 0
130301fe084SFlorian Hahn  %and = and i1 %c.2, %c.1
131301fe084SFlorian Hahn  br i1 %and, label %math, label %exit.fail
132301fe084SFlorian Hahn
133301fe084SFlorian Hahnmath:
134301fe084SFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
135301fe084SFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
136301fe084SFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
137301fe084SFlorian Hahn
138301fe084SFlorian Hahnexit.ok:
139301fe084SFlorian Hahn  ret i8 20
140301fe084SFlorian Hahn
141301fe084SFlorian Hahnexit.fail:
142301fe084SFlorian Hahn  ret i8 0
143301fe084SFlorian Hahn}
144301fe084SFlorian Hahn
14561bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow1(i8 %a, i8 %b) {
14661bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow1(
14761bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
14861bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]]
14961bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
15061bb2e4eSFlorian Hahn; CHECK:       math:
15161bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
15261bb2e4eSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
15361bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
15461bb2e4eSFlorian Hahn; CHECK:       exit.ok:
15561bb2e4eSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
15661bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
15761bb2e4eSFlorian Hahn; CHECK:       exit.fail:
15861bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
15961bb2e4eSFlorian Hahn;
16061bb2e4eSFlorian Hahnentry:
16161bb2e4eSFlorian Hahn  %c.1 = icmp sge i8 %b, %a
16261bb2e4eSFlorian Hahn  br i1 %c.1, label %math, label %exit.fail
16361bb2e4eSFlorian Hahn
16461bb2e4eSFlorian Hahnmath:
16561bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
16661bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
16761bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
16861bb2e4eSFlorian Hahn
16961bb2e4eSFlorian Hahnexit.ok:
17061bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
17161bb2e4eSFlorian Hahn  ret i8 %res
17261bb2e4eSFlorian Hahn
17361bb2e4eSFlorian Hahnexit.fail:
17461bb2e4eSFlorian Hahn  ret i8 0
17561bb2e4eSFlorian Hahn}
17661bb2e4eSFlorian Hahn
17761bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow2(i8 %a, i8 %b) {
17861bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow2(
17961bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
18061bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[A:%.*]], 0
18161bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
18261bb2e4eSFlorian Hahn; CHECK:       math:
18361bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B:%.*]], i8 [[A]])
18461bb2e4eSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
18561bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
18661bb2e4eSFlorian Hahn; CHECK:       exit.ok:
18761bb2e4eSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
18861bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
18961bb2e4eSFlorian Hahn; CHECK:       exit.fail:
19061bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
19161bb2e4eSFlorian Hahn;
19261bb2e4eSFlorian Hahnentry:
19361bb2e4eSFlorian Hahn  %c.1 = icmp sge i8 %a, 0
19461bb2e4eSFlorian Hahn  br i1 %c.1, label %math, label %exit.fail
19561bb2e4eSFlorian Hahn
19661bb2e4eSFlorian Hahnmath:
19761bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
19861bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
19961bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
20061bb2e4eSFlorian Hahn
20161bb2e4eSFlorian Hahnexit.ok:
20261bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
20361bb2e4eSFlorian Hahn  ret i8 %res
20461bb2e4eSFlorian Hahn
20561bb2e4eSFlorian Hahnexit.fail:
20661bb2e4eSFlorian Hahn  ret i8 0
20761bb2e4eSFlorian Hahn}
20861bb2e4eSFlorian Hahn
20961bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow3(i8 %a, i8 %b) {
21061bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow3(
21161bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
21261bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]]
21361bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[A]], -1
21461bb2e4eSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
21561bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
21661bb2e4eSFlorian Hahn; CHECK:       math:
21761bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
21861bb2e4eSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
21961bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
22061bb2e4eSFlorian Hahn; CHECK:       exit.ok:
22161bb2e4eSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
22261bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
22361bb2e4eSFlorian Hahn; CHECK:       exit.fail:
22461bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
22561bb2e4eSFlorian Hahn;
22661bb2e4eSFlorian Hahnentry:
22761bb2e4eSFlorian Hahn  %c.1 = icmp sge i8 %b, %a
22861bb2e4eSFlorian Hahn  %c.2 = icmp sge i8 %a, -1
22961bb2e4eSFlorian Hahn  %and = and i1 %c.2, %c.1
23061bb2e4eSFlorian Hahn  br i1 %and, label %math, label %exit.fail
23161bb2e4eSFlorian Hahn
23261bb2e4eSFlorian Hahnmath:
23361bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
23461bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
23561bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
23661bb2e4eSFlorian Hahn
23761bb2e4eSFlorian Hahnexit.ok:
23861bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
23961bb2e4eSFlorian Hahn  ret i8 %res
24061bb2e4eSFlorian Hahn
24161bb2e4eSFlorian Hahnexit.fail:
24261bb2e4eSFlorian Hahn  ret i8 0
24361bb2e4eSFlorian Hahn}
24461bb2e4eSFlorian Hahn
24561bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow4(i8 %a, i8 %b) {
24661bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow4(
24761bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
24861bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]]
24961bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[A]], 0
25061bb2e4eSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
25161bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
25261bb2e4eSFlorian Hahn; CHECK:       math:
25361bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
25461bb2e4eSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
25561bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
25661bb2e4eSFlorian Hahn; CHECK:       exit.ok:
25761bb2e4eSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
25861bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
25961bb2e4eSFlorian Hahn; CHECK:       exit.fail:
26061bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
26161bb2e4eSFlorian Hahn;
26261bb2e4eSFlorian Hahnentry:
26361bb2e4eSFlorian Hahn  %c.1 = icmp uge i8 %b, %a
26461bb2e4eSFlorian Hahn  %c.2 = icmp sge i8 %a, 0
26561bb2e4eSFlorian Hahn  %and = and i1 %c.2, %c.1
26661bb2e4eSFlorian Hahn  br i1 %and, label %math, label %exit.fail
26761bb2e4eSFlorian Hahn
26861bb2e4eSFlorian Hahnmath:
26961bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
27061bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
27161bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
27261bb2e4eSFlorian Hahn
27361bb2e4eSFlorian Hahnexit.ok:
27461bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
27561bb2e4eSFlorian Hahn  ret i8 %res
27661bb2e4eSFlorian Hahn
27761bb2e4eSFlorian Hahnexit.fail:
27861bb2e4eSFlorian Hahn  ret i8 0
27961bb2e4eSFlorian Hahn}
2801911843cSFlorian Hahn
2811911843cSFlorian Hahndefine i8 @ssub_may_overflow5(i8 %a, i8 %b) {
2821911843cSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow5(
2831911843cSFlorian Hahn; CHECK-NEXT:  entry:
2841911843cSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]]
2851911843cSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[B]], 0
2861911843cSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
2871911843cSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
2881911843cSFlorian Hahn; CHECK:       math:
2891911843cSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
2901911843cSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
2911911843cSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
2921911843cSFlorian Hahn; CHECK:       exit.ok:
2931911843cSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
2941911843cSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
2951911843cSFlorian Hahn; CHECK:       exit.fail:
2961911843cSFlorian Hahn; CHECK-NEXT:    ret i8 0
2971911843cSFlorian Hahn;
2981911843cSFlorian Hahnentry:
2991911843cSFlorian Hahn  %c.1 = icmp sge i8 %b, %a
3001911843cSFlorian Hahn  %c.2 = icmp sge i8 %b, 0
3011911843cSFlorian Hahn  %and = and i1 %c.2, %c.1
3021911843cSFlorian Hahn  br i1 %and, label %math, label %exit.fail
3031911843cSFlorian Hahn
3041911843cSFlorian Hahnmath:
3051911843cSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
3061911843cSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
3071911843cSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
3081911843cSFlorian Hahn
3091911843cSFlorian Hahnexit.ok:
3101911843cSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
3111911843cSFlorian Hahn  ret i8 %res
3121911843cSFlorian Hahn
3131911843cSFlorian Hahnexit.fail:
3141911843cSFlorian Hahn  ret i8 0
3151911843cSFlorian Hahn}
3161911843cSFlorian Hahn
3171911843cSFlorian Hahndefine i8 @ssub_may_overflow6(i8 %a, i8 %b) {
3181911843cSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow6(
3191911843cSFlorian Hahn; CHECK-NEXT:  entry:
3201911843cSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sle i8 [[B:%.*]], [[A:%.*]]
3211911843cSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i8 [[B]], 0
3221911843cSFlorian Hahn; CHECK-NEXT:    [[OR_COND:%.*]] = or i1 [[C_2]], [[C_1]]
3231911843cSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_COND]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
3241911843cSFlorian Hahn; CHECK:       math:
3251911843cSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
3261911843cSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
3271911843cSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
3281911843cSFlorian Hahn; CHECK:       exit.ok:
3291911843cSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
3301911843cSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
3311911843cSFlorian Hahn; CHECK:       exit.fail:
3321911843cSFlorian Hahn; CHECK-NEXT:    ret i8 0
3331911843cSFlorian Hahn;
3341911843cSFlorian Hahnentry:
3351911843cSFlorian Hahn  %c.1 = icmp sle i8 %b, %a
3361911843cSFlorian Hahn  %c.2 = icmp slt i8 %b, 0
3371911843cSFlorian Hahn  %or.cond = or i1 %c.2, %c.1
3381911843cSFlorian Hahn  br i1 %or.cond, label %exit.fail, label %math
3391911843cSFlorian Hahn
3401911843cSFlorian Hahnmath:
3411911843cSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
3421911843cSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
3431911843cSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
3441911843cSFlorian Hahn
3451911843cSFlorian Hahnexit.ok:
3461911843cSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
3471911843cSFlorian Hahn  ret i8 %res
3481911843cSFlorian Hahn
3491911843cSFlorian Hahnexit.fail:
3501911843cSFlorian Hahn  ret i8 0
3511911843cSFlorian Hahn}
352