Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / RISCV / float-bitmanip-dagcombines.ll
blob53df588bf1c374a76b22357f755b087a24244666
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN:   | FileCheck -check-prefix=RV32I %s
4 ; RUN: llc -mtriple=riscv32 -target-abi ilp32 -mattr=+f -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck -check-prefix=RV32IF %s
6 ; RUN: llc -mtriple=riscv32 -target-abi ilp32 -mattr=+zfinx -verify-machineinstrs < %s \
7 ; RUN:   | FileCheck -check-prefix=RV32IZFINX %s
8 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
9 ; RUN:   | FileCheck -check-prefix=RV64I %s
10 ; RUN: llc -mtriple=riscv64 -target-abi lp64 -mattr=+f -verify-machineinstrs < %s \
11 ; RUN:   | FileCheck -check-prefix=RV64IF %s
12 ; RUN: llc -mtriple=riscv64 -target-abi lp64 -mattr=+zfinx -verify-machineinstrs < %s \
13 ; RUN:   | FileCheck -check-prefix=RV64IZFINX %s
15 ; This file tests cases where simple floating point operations can be
16 ; profitably handled though bit manipulation if a soft-float ABI is being used
17 ; (e.g. fneg implemented by XORing the sign bit). This is typically handled in
18 ; DAGCombiner::visitBITCAST, but this target-independent code may not trigger
19 ; in cases where we perform custom legalisation (e.g. RV64F).
21 define float @fneg(float %a) nounwind {
22 ; RV32I-LABEL: fneg:
23 ; RV32I:       # %bb.0:
24 ; RV32I-NEXT:    lui a1, 524288
25 ; RV32I-NEXT:    xor a0, a0, a1
26 ; RV32I-NEXT:    ret
28 ; RV32IF-LABEL: fneg:
29 ; RV32IF:       # %bb.0:
30 ; RV32IF-NEXT:    lui a1, 524288
31 ; RV32IF-NEXT:    xor a0, a0, a1
32 ; RV32IF-NEXT:    ret
34 ; RV32IZFINX-LABEL: fneg:
35 ; RV32IZFINX:       # %bb.0:
36 ; RV32IZFINX-NEXT:    lui a1, 524288
37 ; RV32IZFINX-NEXT:    xor a0, a0, a1
38 ; RV32IZFINX-NEXT:    ret
40 ; RV64I-LABEL: fneg:
41 ; RV64I:       # %bb.0:
42 ; RV64I-NEXT:    lui a1, 524288
43 ; RV64I-NEXT:    xor a0, a0, a1
44 ; RV64I-NEXT:    ret
46 ; RV64IF-LABEL: fneg:
47 ; RV64IF:       # %bb.0:
48 ; RV64IF-NEXT:    lui a1, 524288
49 ; RV64IF-NEXT:    xor a0, a0, a1
50 ; RV64IF-NEXT:    ret
52 ; RV64IZFINX-LABEL: fneg:
53 ; RV64IZFINX:       # %bb.0:
54 ; RV64IZFINX-NEXT:    lui a1, 524288
55 ; RV64IZFINX-NEXT:    xor a0, a0, a1
56 ; RV64IZFINX-NEXT:    ret
57   %1 = fneg float %a
58   ret float %1
61 declare float @llvm.fabs.f32(float)
63 define float @fabs(float %a) nounwind {
64 ; RV32I-LABEL: fabs:
65 ; RV32I:       # %bb.0:
66 ; RV32I-NEXT:    slli a0, a0, 1
67 ; RV32I-NEXT:    srli a0, a0, 1
68 ; RV32I-NEXT:    ret
70 ; RV32IF-LABEL: fabs:
71 ; RV32IF:       # %bb.0:
72 ; RV32IF-NEXT:    slli a0, a0, 1
73 ; RV32IF-NEXT:    srli a0, a0, 1
74 ; RV32IF-NEXT:    ret
76 ; RV32IZFINX-LABEL: fabs:
77 ; RV32IZFINX:       # %bb.0:
78 ; RV32IZFINX-NEXT:    slli a0, a0, 1
79 ; RV32IZFINX-NEXT:    srli a0, a0, 1
80 ; RV32IZFINX-NEXT:    ret
82 ; RV64I-LABEL: fabs:
83 ; RV64I:       # %bb.0:
84 ; RV64I-NEXT:    slli a0, a0, 33
85 ; RV64I-NEXT:    srli a0, a0, 33
86 ; RV64I-NEXT:    ret
88 ; RV64IF-LABEL: fabs:
89 ; RV64IF:       # %bb.0:
90 ; RV64IF-NEXT:    slli a0, a0, 33
91 ; RV64IF-NEXT:    srli a0, a0, 33
92 ; RV64IF-NEXT:    ret
94 ; RV64IZFINX-LABEL: fabs:
95 ; RV64IZFINX:       # %bb.0:
96 ; RV64IZFINX-NEXT:    slli a0, a0, 33
97 ; RV64IZFINX-NEXT:    srli a0, a0, 33
98 ; RV64IZFINX-NEXT:    ret
99   %1 = call float @llvm.fabs.f32(float %a)
100   ret float %1
103 declare float @llvm.copysign.f32(float, float)
105 ; DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN will convert to bitwise
106 ; operations if floating point isn't supported. A combine could be written to
107 ; do the same even when f32 is legal.
109 define float @fcopysign_fneg(float %a, float %b) nounwind {
110 ; RV32I-LABEL: fcopysign_fneg:
111 ; RV32I:       # %bb.0:
112 ; RV32I-NEXT:    not a1, a1
113 ; RV32I-NEXT:    lui a2, 524288
114 ; RV32I-NEXT:    and a1, a1, a2
115 ; RV32I-NEXT:    slli a0, a0, 1
116 ; RV32I-NEXT:    srli a0, a0, 1
117 ; RV32I-NEXT:    or a0, a0, a1
118 ; RV32I-NEXT:    ret
120 ; RV32IF-LABEL: fcopysign_fneg:
121 ; RV32IF:       # %bb.0:
122 ; RV32IF-NEXT:    fmv.w.x fa5, a0
123 ; RV32IF-NEXT:    not a0, a1
124 ; RV32IF-NEXT:    fmv.w.x fa4, a0
125 ; RV32IF-NEXT:    fsgnj.s fa5, fa5, fa4
126 ; RV32IF-NEXT:    fmv.x.w a0, fa5
127 ; RV32IF-NEXT:    ret
129 ; RV32IZFINX-LABEL: fcopysign_fneg:
130 ; RV32IZFINX:       # %bb.0:
131 ; RV32IZFINX-NEXT:    not a1, a1
132 ; RV32IZFINX-NEXT:    fsgnj.s a0, a0, a1
133 ; RV32IZFINX-NEXT:    ret
135 ; RV64I-LABEL: fcopysign_fneg:
136 ; RV64I:       # %bb.0:
137 ; RV64I-NEXT:    not a1, a1
138 ; RV64I-NEXT:    lui a2, 524288
139 ; RV64I-NEXT:    and a1, a1, a2
140 ; RV64I-NEXT:    slli a0, a0, 33
141 ; RV64I-NEXT:    srli a0, a0, 33
142 ; RV64I-NEXT:    or a0, a0, a1
143 ; RV64I-NEXT:    ret
145 ; RV64IF-LABEL: fcopysign_fneg:
146 ; RV64IF:       # %bb.0:
147 ; RV64IF-NEXT:    fmv.w.x fa5, a1
148 ; RV64IF-NEXT:    fmv.w.x fa4, a0
149 ; RV64IF-NEXT:    fsgnjn.s fa5, fa4, fa5
150 ; RV64IF-NEXT:    fmv.x.w a0, fa5
151 ; RV64IF-NEXT:    ret
153 ; RV64IZFINX-LABEL: fcopysign_fneg:
154 ; RV64IZFINX:       # %bb.0:
155 ; RV64IZFINX-NEXT:    fsgnjn.s a0, a0, a1
156 ; RV64IZFINX-NEXT:    ret
157   %1 = fneg float %b
158   %2 = call float @llvm.copysign.f32(float %a, float %1)
159   ret float %2