xref: /llvm-project/llvm/test/Transforms/PhaseOrdering/min-max-abs-cse.ll (revision 43acb61a08fffada31fb2e20e45fcc8492ef76b9)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -S -O1 | FileCheck %s
3; RUN: opt -passes='default<O1>' -S < %s | FileCheck %s
4
5; In all tests, expect instcombine to canonicalize the select patterns
6; for min/max/abs to allow CSE and subsequent simplification.
7
8; TODO:
9; This should be reduced to 0, but we are missing some
10; fold(s) in instcombine.
11
12define i8 @smax_nsw(i8 %a, i8 %b) {
13; CHECK-LABEL: @smax_nsw(
14; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i8 [[A:%.*]], [[B:%.*]]
15; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i8 [[A]], [[B]]
16; CHECK-NEXT:    [[M1:%.*]] = select i1 [[CMP1]], i8 0, i8 [[SUB]]
17; CHECK-NEXT:    [[TMP1:%.*]] = tail call i8 @llvm.smax.i8(i8 [[SUB]], i8 0)
18; CHECK-NEXT:    [[R:%.*]] = sub i8 [[TMP1]], [[M1]]
19; CHECK-NEXT:    ret i8 [[R]]
20;
21  %sub = sub nsw i8 %a, %b
22  %cmp1 = icmp slt i8 %a, %b
23  %cmp2 = icmp sgt i8 %sub, 0
24  %m1 = select i1 %cmp1, i8 0, i8 %sub
25  %m2 = select i1 %cmp2, i8 %sub, i8 0
26  %r = sub i8 %m2, %m1
27  ret i8 %r
28}
29
30; or (abs a), (abs a) --> abs a
31
32define i8 @abs_swapped(i8 %a) {
33; CHECK-LABEL: @abs_swapped(
34; CHECK-NEXT:    [[TMP1:%.*]] = tail call i8 @llvm.abs.i8(i8 [[A:%.*]], i1 false)
35; CHECK-NEXT:    ret i8 [[TMP1]]
36;
37  %neg = sub i8 0, %a
38  %cmp1 = icmp sgt i8 %a, 0
39  %cmp2 = icmp slt i8 %a, 0
40  %m1 = select i1 %cmp1, i8 %a, i8 %neg
41  %m2 = select i1 %cmp2, i8 %neg, i8 %a
42  %r = or i8 %m2, %m1
43  ret i8 %r
44}
45
46; xor (nabs a), (nabs a) --> 0
47
48define i8 @nabs_swapped(i8 %a) {
49; CHECK-LABEL: @nabs_swapped(
50; CHECK-NEXT:    ret i8 0
51;
52  %neg = sub i8 0, %a
53  %cmp1 = icmp slt i8 %a, 0
54  %cmp2 = icmp sgt i8 %a, 0
55  %m1 = select i1 %cmp1, i8 %a, i8 %neg
56  %m2 = select i1 %cmp2, i8 %neg, i8 %a
57  %r = xor i8 %m2, %m1
58  ret i8 %r
59}
60
61; xor (abs a), (abs a) --> 0
62
63define i8 @abs_different_constants(i8 %a) {
64; CHECK-LABEL: @abs_different_constants(
65; CHECK-NEXT:    ret i8 0
66;
67  %neg = sub i8 0, %a
68  %cmp1 = icmp sgt i8 %a, -1
69  %cmp2 = icmp slt i8 %a, 0
70  %m1 = select i1 %cmp1, i8 %a, i8 %neg
71  %m2 = select i1 %cmp2, i8 %neg, i8 %a
72  %r = xor i8 %m2, %m1
73  ret i8 %r
74}
75
76; or (nabs a), (nabs a) --> nabs a
77
78define i8 @nabs_different_constants(i8 %a) {
79; CHECK-LABEL: @nabs_different_constants(
80; CHECK-NEXT:    [[TMP1:%.*]] = tail call i8 @llvm.abs.i8(i8 [[A:%.*]], i1 false)
81; CHECK-NEXT:    [[M1:%.*]] = sub i8 0, [[TMP1]]
82; CHECK-NEXT:    ret i8 [[M1]]
83;
84  %neg = sub i8 0, %a
85  %cmp1 = icmp slt i8 %a, 0
86  %cmp2 = icmp sgt i8 %a, -1
87  %m1 = select i1 %cmp1, i8 %a, i8 %neg
88  %m2 = select i1 %cmp2, i8 %neg, i8 %a
89  %r = or i8 %m2, %m1
90  ret i8 %r
91}
92