[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / RISCV / float-bitmanip-dagcombines.ll
blob215fe5839ef7e160d1ee25d16ef8aabb9a1272b9
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 -mattr=+f -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck -check-prefix=RV32IF %s
6 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
7 ; RUN:   | FileCheck -check-prefix=RV64I %s
8 ; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
9 ; RUN:   | FileCheck -check-prefix=RV64IF %s
11 ; This file tests cases where simple floating point operations can be
12 ; profitably handled though bit manipulation if a soft-float ABI is being used
13 ; (e.g. fneg implemented by XORing the sign bit). This is typically handled in
14 ; DAGCombiner::visitBITCAST, but this target-independent code may not trigger
15 ; in cases where we perform custom legalisation (e.g. RV64F).
17 define float @fneg(float %a) nounwind {
18 ; RV32I-LABEL: fneg:
19 ; RV32I:       # %bb.0:
20 ; RV32I-NEXT:    lui a1, 524288
21 ; RV32I-NEXT:    xor a0, a0, a1
22 ; RV32I-NEXT:    ret
24 ; RV32IF-LABEL: fneg:
25 ; RV32IF:       # %bb.0:
26 ; RV32IF-NEXT:    lui a1, 524288
27 ; RV32IF-NEXT:    xor a0, a0, a1
28 ; RV32IF-NEXT:    ret
30 ; RV64I-LABEL: fneg:
31 ; RV64I:       # %bb.0:
32 ; RV64I-NEXT:    lui a1, 524288
33 ; RV64I-NEXT:    xor a0, a0, a1
34 ; RV64I-NEXT:    ret
36 ; RV64IF-LABEL: fneg:
37 ; RV64IF:       # %bb.0:
38 ; RV64IF-NEXT:    lui a1, 524288
39 ; RV64IF-NEXT:    xor a0, a0, a1
40 ; RV64IF-NEXT:    ret
41   %1 = fneg float %a
42   ret float %1
45 declare float @llvm.fabs.f32(float)
47 define float @fabs(float %a) nounwind {
48 ; RV32I-LABEL: fabs:
49 ; RV32I:       # %bb.0:
50 ; RV32I-NEXT:    lui a1, 524288
51 ; RV32I-NEXT:    addi a1, a1, -1
52 ; RV32I-NEXT:    and a0, a0, a1
53 ; RV32I-NEXT:    ret
55 ; RV32IF-LABEL: fabs:
56 ; RV32IF:       # %bb.0:
57 ; RV32IF-NEXT:    lui a1, 524288
58 ; RV32IF-NEXT:    addi a1, a1, -1
59 ; RV32IF-NEXT:    and a0, a0, a1
60 ; RV32IF-NEXT:    ret
62 ; RV64I-LABEL: fabs:
63 ; RV64I:       # %bb.0:
64 ; RV64I-NEXT:    lui a1, 524288
65 ; RV64I-NEXT:    addiw a1, a1, -1
66 ; RV64I-NEXT:    and a0, a0, a1
67 ; RV64I-NEXT:    ret
69 ; RV64IF-LABEL: fabs:
70 ; RV64IF:       # %bb.0:
71 ; RV64IF-NEXT:    lui a1, 524288
72 ; RV64IF-NEXT:    addiw a1, a1, -1
73 ; RV64IF-NEXT:    and a0, a0, a1
74 ; RV64IF-NEXT:    ret
75   %1 = call float @llvm.fabs.f32(float %a)
76   ret float %1
79 declare float @llvm.copysign.f32(float, float)
81 ; DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN will convert to bitwise
82 ; operations if floating point isn't supported. A combine could be written to
83 ; do the same even when f32 is legal.
85 define float @fcopysign_fneg(float %a, float %b) nounwind {
86 ; RV32I-LABEL: fcopysign_fneg:
87 ; RV32I:       # %bb.0:
88 ; RV32I-NEXT:    not a1, a1
89 ; RV32I-NEXT:    lui a2, 524288
90 ; RV32I-NEXT:    and a1, a1, a2
91 ; RV32I-NEXT:    addi a2, a2, -1
92 ; RV32I-NEXT:    and a0, a0, a2
93 ; RV32I-NEXT:    or a0, a0, a1
94 ; RV32I-NEXT:    ret
96 ; RV32IF-LABEL: fcopysign_fneg:
97 ; RV32IF:       # %bb.0:
98 ; RV32IF-NEXT:    lui a2, 524288
99 ; RV32IF-NEXT:    xor a1, a1, a2
100 ; RV32IF-NEXT:    fmv.w.x ft0, a1
101 ; RV32IF-NEXT:    fmv.w.x ft1, a0
102 ; RV32IF-NEXT:    fsgnj.s ft0, ft1, ft0
103 ; RV32IF-NEXT:    fmv.x.w a0, ft0
104 ; RV32IF-NEXT:    ret
106 ; RV64I-LABEL: fcopysign_fneg:
107 ; RV64I:       # %bb.0:
108 ; RV64I-NEXT:    not a1, a1
109 ; RV64I-NEXT:    lui a2, 524288
110 ; RV64I-NEXT:    and a1, a1, a2
111 ; RV64I-NEXT:    addiw a2, a2, -1
112 ; RV64I-NEXT:    and a0, a0, a2
113 ; RV64I-NEXT:    or a0, a0, a1
114 ; RV64I-NEXT:    ret
116 ; RV64IF-LABEL: fcopysign_fneg:
117 ; RV64IF:       # %bb.0:
118 ; RV64IF-NEXT:    fmv.w.x ft0, a1
119 ; RV64IF-NEXT:    fmv.w.x ft1, a0
120 ; RV64IF-NEXT:    fsgnjn.s ft0, ft1, ft0
121 ; RV64IF-NEXT:    fmv.x.w a0, ft0
122 ; RV64IF-NEXT:    ret
123   %1 = fneg float %b
124   %2 = call float @llvm.copysign.f32(float %a, float %1)
125   ret float %2