[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / CodeGen / RISCV / float-bitmanip-dagcombines.ll
blobaaeb1b7c0b1fb16b465fdc7c84c7eade56f7d059
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:    fneg.s a0, a0
37 ; RV32IZFINX-NEXT:    ret
39 ; RV64I-LABEL: fneg:
40 ; RV64I:       # %bb.0:
41 ; RV64I-NEXT:    lui a1, 524288
42 ; RV64I-NEXT:    xor a0, a0, a1
43 ; RV64I-NEXT:    ret
45 ; RV64IF-LABEL: fneg:
46 ; RV64IF:       # %bb.0:
47 ; RV64IF-NEXT:    lui a1, 524288
48 ; RV64IF-NEXT:    xor a0, a0, a1
49 ; RV64IF-NEXT:    ret
51 ; RV64IZFINX-LABEL: fneg:
52 ; RV64IZFINX:       # %bb.0:
53 ; RV64IZFINX-NEXT:    fneg.s a0, a0
54 ; RV64IZFINX-NEXT:    ret
55   %1 = fneg float %a
56   ret float %1
59 declare float @llvm.fabs.f32(float)
61 define float @fabs(float %a) nounwind {
62 ; RV32I-LABEL: fabs:
63 ; RV32I:       # %bb.0:
64 ; RV32I-NEXT:    slli a0, a0, 1
65 ; RV32I-NEXT:    srli a0, a0, 1
66 ; RV32I-NEXT:    ret
68 ; RV32IF-LABEL: fabs:
69 ; RV32IF:       # %bb.0:
70 ; RV32IF-NEXT:    slli a0, a0, 1
71 ; RV32IF-NEXT:    srli a0, a0, 1
72 ; RV32IF-NEXT:    ret
74 ; RV32IZFINX-LABEL: fabs:
75 ; RV32IZFINX:       # %bb.0:
76 ; RV32IZFINX-NEXT:    fabs.s a0, a0
77 ; RV32IZFINX-NEXT:    ret
79 ; RV64I-LABEL: fabs:
80 ; RV64I:       # %bb.0:
81 ; RV64I-NEXT:    slli a0, a0, 33
82 ; RV64I-NEXT:    srli a0, a0, 33
83 ; RV64I-NEXT:    ret
85 ; RV64IF-LABEL: fabs:
86 ; RV64IF:       # %bb.0:
87 ; RV64IF-NEXT:    slli a0, a0, 33
88 ; RV64IF-NEXT:    srli a0, a0, 33
89 ; RV64IF-NEXT:    ret
91 ; RV64IZFINX-LABEL: fabs:
92 ; RV64IZFINX:       # %bb.0:
93 ; RV64IZFINX-NEXT:    fabs.s a0, a0
94 ; RV64IZFINX-NEXT:    ret
95   %1 = call float @llvm.fabs.f32(float %a)
96   ret float %1
99 declare float @llvm.copysign.f32(float, float)
101 ; DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN will convert to bitwise
102 ; operations if floating point isn't supported. A combine could be written to
103 ; do the same even when f32 is legal.
105 define float @fcopysign_fneg(float %a, float %b) nounwind {
106 ; RV32I-LABEL: fcopysign_fneg:
107 ; RV32I:       # %bb.0:
108 ; RV32I-NEXT:    not a1, a1
109 ; RV32I-NEXT:    lui a2, 524288
110 ; RV32I-NEXT:    slli a0, a0, 1
111 ; RV32I-NEXT:    and a1, a1, a2
112 ; RV32I-NEXT:    srli a0, a0, 1
113 ; RV32I-NEXT:    or a0, a0, a1
114 ; RV32I-NEXT:    ret
116 ; RV32IF-LABEL: fcopysign_fneg:
117 ; RV32IF:       # %bb.0:
118 ; RV32IF-NEXT:    fmv.w.x fa5, a0
119 ; RV32IF-NEXT:    not a0, a1
120 ; RV32IF-NEXT:    fmv.w.x fa4, a0
121 ; RV32IF-NEXT:    fsgnj.s fa5, fa5, fa4
122 ; RV32IF-NEXT:    fmv.x.w a0, fa5
123 ; RV32IF-NEXT:    ret
125 ; RV32IZFINX-LABEL: fcopysign_fneg:
126 ; RV32IZFINX:       # %bb.0:
127 ; RV32IZFINX-NEXT:    fsgnjn.s a0, a0, a1
128 ; RV32IZFINX-NEXT:    ret
130 ; RV64I-LABEL: fcopysign_fneg:
131 ; RV64I:       # %bb.0:
132 ; RV64I-NEXT:    not a1, a1
133 ; RV64I-NEXT:    lui a2, 524288
134 ; RV64I-NEXT:    slli a0, a0, 33
135 ; RV64I-NEXT:    and a1, a1, a2
136 ; RV64I-NEXT:    srli a0, a0, 33
137 ; RV64I-NEXT:    or a0, a0, a1
138 ; RV64I-NEXT:    ret
140 ; RV64IF-LABEL: fcopysign_fneg:
141 ; RV64IF:       # %bb.0:
142 ; RV64IF-NEXT:    fmv.w.x fa5, a1
143 ; RV64IF-NEXT:    fmv.w.x fa4, a0
144 ; RV64IF-NEXT:    fsgnjn.s fa5, fa4, fa5
145 ; RV64IF-NEXT:    fmv.x.w a0, fa5
146 ; RV64IF-NEXT:    ret
148 ; RV64IZFINX-LABEL: fcopysign_fneg:
149 ; RV64IZFINX:       # %bb.0:
150 ; RV64IZFINX-NEXT:    fsgnjn.s a0, a0, a1
151 ; RV64IZFINX-NEXT:    ret
152   %1 = fneg float %b
153   %2 = call float @llvm.copysign.f32(float %a, float %1)
154   ret float %2