1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
; Tests folding constants from two similar selects that feed a add
define float @test1a(i1 zeroext %arg) #0 {
; CHECK-LABEL: @test1a(
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[ARG:%.*]], float 6.000000e+00, float 1.500000e+01
; CHECK-NEXT: ret float [[TMP2]]
;
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
%tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
%tmp2 = fadd float %tmp, %tmp1
ret float %tmp2
}
; Tests folding multiple expression constants from similar selects that feed a adds
define float @test1b(i1 zeroext %arg) #0 {
; CHECK-LABEL: @test1b(
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[ARG:%.*]], float 7.250000e+00, float 2.800000e+01
; CHECK-NEXT: ret float [[TMP5]]
;
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
%tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
%tmp2 = select i1 %arg, float 2.500000e-01, float 4.000000e+00
%tmp3 = fadd float %tmp, %tmp1
%tmp4 = fadd float %tmp2, %tmp1
%tmp5 = fadd float %tmp4, %tmp3
ret float %tmp5
}
; Tests folding constants from two similar selects that feed a sub
define float @test2(i1 zeroext %arg) #0 {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[ARG:%.*]], float 4.000000e+00, float -3.000000e+00
; CHECK-NEXT: ret float [[TMP2]]
;
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
%tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
%tmp2 = fsub float %tmp, %tmp1
ret float %tmp2
}
; Tests folding constants from two similar selects that feed a mul
define float @test3(i1 zeroext %arg) #0 {
; CHECK-LABEL: @test3(
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[ARG:%.*]], float 5.000000e+00, float 5.400000e+01
; CHECK-NEXT: ret float [[TMP2]]
;
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
%tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
%tmp2 = fmul float %tmp, %tmp1
ret float %tmp2
}
declare void @use_float(float)
; Tests folding constants if the selects have multiple uses but
; we can fold away the binary op with a select.
define float @test4(i1 zeroext %arg) #0 {
; CHECK-LABEL: @test4(
; CHECK-NEXT: [[TMP:%.*]] = select i1 [[ARG:%.*]], float 5.000000e+00, float 6.000000e+00
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[ARG]], float 5.000000e+00, float 5.400000e+01
; CHECK-NEXT: call void @use_float(float [[TMP]])
; CHECK-NEXT: ret float [[TMP2]]
;
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
%tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
%tmp2 = fmul float %tmp, %tmp1
call void @use_float(float %tmp)
ret float %tmp2
}
; Tests not folding constants if we cannot fold away any of the selects.
define float @test5(i1 zeroext %arg, float %div) {
; CHECK-LABEL: @test5(
; CHECK-NEXT: [[TMP:%.*]] = select i1 [[ARG:%.*]], float [[DIV:%.*]], float 5.000000e+00
; CHECK-NEXT: [[MUL:%.*]] = fmul contract float [[TMP]], [[TMP]]
; CHECK-NEXT: call void @use_float(float [[TMP]])
; CHECK-NEXT: ret float [[MUL]]
;
%tmp = select i1 %arg, float %div, float 5.000000e+00
%mul = fmul contract float %tmp, %tmp
call void @use_float(float %tmp)
ret float %mul
}
define float @fmul_nnan_nsz(i1 %cond, float %val) {
; CHECK-LABEL: @fmul_nnan_nsz(
; CHECK-NEXT: ret float 0.000000e+00
;
%lhs = select i1 %cond, float %val, float +0.0
%rhs = select i1 %cond, float -0.0, float %val
%mul = fmul nnan nsz float %lhs, %rhs
ret float %mul
}
define <2 x float> @fadd_nsz(<2 x i1> %cond, <2 x float> %val) {
; CHECK-LABEL: @fadd_nsz(
; CHECK-NEXT: ret <2 x float> [[VAL:%.*]]
;
%lhs = select <2 x i1> %cond, <2 x float> %val, <2 x float> <float +0.0, float +0.0>
%rhs = select <2 x i1> %cond, <2 x float> <float +0.0, float +0.0>, <2 x float> %val
%add = fadd nsz <2 x float> %lhs, %rhs
ret <2 x float> %add
}
define double @fsub_nnan(i1 %cond, double %val, double %val2) {
; CHECK-LABEL: @fsub_nnan(
; CHECK-NEXT: [[TMP1:%.*]] = fadd nnan double [[VAL2:%.*]], -7.000000e+00
; CHECK-NEXT: [[ADD:%.*]] = select nnan i1 [[COND:%.*]], double 0.000000e+00, double [[TMP1]]
; CHECK-NEXT: ret double [[ADD]]
;
%lhs = select i1 %cond, double %val, double %val2
%rhs = select i1 %cond, double %val, double 7.0
%add = fsub nnan double %lhs, %rhs
ret double %add
}
; TODO combine selects feeding fdiv like we do for fmul, fadd and fsub
define double @fdiv_nnan_nsz(i1 %cond, double %val, double %val2) {
; CHECK-LABEL: @fdiv_nnan_nsz(
; CHECK-NEXT: [[LHS:%.*]] = select i1 [[COND:%.*]], double [[VAL2:%.*]], double 0.000000e+00
; CHECK-NEXT: [[RHS:%.*]] = select i1 [[COND]], double 4.200000e+01, double [[VAL:%.*]]
; CHECK-NEXT: [[ADD:%.*]] = fdiv nnan nsz double [[LHS]], [[RHS]]
; CHECK-NEXT: ret double [[ADD]]
;
%lhs = select i1 %cond, double %val2, double 0.0
%rhs = select i1 %cond, double 42.0, double %val
%add = fdiv nnan nsz double %lhs, %rhs
ret double %add
}
|