llvm.org GIT mirror llvm / 22d8eff
[RISCV] Add another potential combine to {double,float}-bitmanip-dagcombines.ll (fcopysign a, (fneg b)) will be expanded to bitwise operations by DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN if the floating point type isn't legal. Arguably it might be worth doing a combine even if it is legal. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352240 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Bradbury 1 year, 4 months ago
2 changed file(s) with 103 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
7777 %1 = call double @llvm.fabs.f64(double %a)
7878 ret double %1
7979 }
80
81 declare double @llvm.copysign.f64(double, double)
82
83 ; DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN will convert to bitwise
84 ; operations if floating point isn't supported. A combine could be written to
85 ; do the same even when f64 is legal.
86
87 define double @fcopysign_fneg(double %a, double %b) nounwind {
88 ; RV32I-LABEL: fcopysign_fneg:
89 ; RV32I: # %bb.0:
90 ; RV32I-NEXT: not a2, a3
91 ; RV32I-NEXT: lui a3, 524288
92 ; RV32I-NEXT: and a2, a2, a3
93 ; RV32I-NEXT: addi a3, a3, -1
94 ; RV32I-NEXT: and a1, a1, a3
95 ; RV32I-NEXT: or a1, a1, a2
96 ; RV32I-NEXT: ret
97 ;
98 ; RV32IFD-LABEL: fcopysign_fneg:
99 ; RV32IFD: # %bb.0:
100 ; RV32IFD-NEXT: addi sp, sp, -16
101 ; RV32IFD-NEXT: sw a2, 8(sp)
102 ; RV32IFD-NEXT: sw a3, 12(sp)
103 ; RV32IFD-NEXT: fld ft0, 8(sp)
104 ; RV32IFD-NEXT: sw a0, 8(sp)
105 ; RV32IFD-NEXT: sw a1, 12(sp)
106 ; RV32IFD-NEXT: fld ft1, 8(sp)
107 ; RV32IFD-NEXT: fsgnjn.d ft0, ft1, ft0
108 ; RV32IFD-NEXT: fsd ft0, 8(sp)
109 ; RV32IFD-NEXT: lw a0, 8(sp)
110 ; RV32IFD-NEXT: lw a1, 12(sp)
111 ; RV32IFD-NEXT: addi sp, sp, 16
112 ; RV32IFD-NEXT: ret
113 ;
114 ; RV64I-LABEL: fcopysign_fneg:
115 ; RV64I: # %bb.0:
116 ; RV64I-NEXT: addi a2, zero, -1
117 ; RV64I-NEXT: slli a2, a2, 63
118 ; RV64I-NEXT: not a1, a1
119 ; RV64I-NEXT: and a1, a1, a2
120 ; RV64I-NEXT: addi a2, a2, -1
121 ; RV64I-NEXT: and a0, a0, a2
122 ; RV64I-NEXT: or a0, a0, a1
123 ; RV64I-NEXT: ret
124 %1 = fneg double %b
125 %2 = call double @llvm.copysign.f64(double %a, double %1)
126 ret double %2
127 }
11 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
22 ; RUN: | FileCheck -check-prefix=RV32I %s
33 ; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \
4 ; RUN: | FileCheck -check-prefix=RV32I %s
4 ; RUN: | FileCheck -check-prefix=RV32IF %s
55 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
66 ; RUN: | FileCheck -check-prefix=RV64I %s
77
1717 ; RV32I-NEXT: lui a1, 524288
1818 ; RV32I-NEXT: xor a0, a0, a1
1919 ; RV32I-NEXT: ret
20 ;
21 ; RV32IF-LABEL: fneg:
22 ; RV32IF: # %bb.0:
23 ; RV32IF-NEXT: lui a1, 524288
24 ; RV32IF-NEXT: xor a0, a0, a1
25 ; RV32IF-NEXT: ret
2026 ;
2127 ; RV64I-LABEL: fneg:
2228 ; RV64I: # %bb.0:
3743 ; RV32I-NEXT: and a0, a0, a1
3844 ; RV32I-NEXT: ret
3945 ;
46 ; RV32IF-LABEL: fabs:
47 ; RV32IF: # %bb.0:
48 ; RV32IF-NEXT: lui a1, 524288
49 ; RV32IF-NEXT: addi a1, a1, -1
50 ; RV32IF-NEXT: and a0, a0, a1
51 ; RV32IF-NEXT: ret
52 ;
4053 ; RV64I-LABEL: fabs:
4154 ; RV64I: # %bb.0:
4255 ; RV64I-NEXT: lui a1, 524288
4659 %1 = call float @llvm.fabs.f32(float %a)
4760 ret float %1
4861 }
62
63 declare float @llvm.copysign.f32(float, float)
64
65 ; DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN will convert to bitwise
66 ; operations if floating point isn't supported. A combine could be written to
67 ; do the same even when f32 is legal.
68
69 define float @fcopysign_fneg(float %a, float %b) nounwind {
70 ; RV32I-LABEL: fcopysign_fneg:
71 ; RV32I: # %bb.0:
72 ; RV32I-NEXT: not a1, a1
73 ; RV32I-NEXT: lui a2, 524288
74 ; RV32I-NEXT: and a1, a1, a2
75 ; RV32I-NEXT: addi a2, a2, -1
76 ; RV32I-NEXT: and a0, a0, a2
77 ; RV32I-NEXT: or a0, a0, a1
78 ; RV32I-NEXT: ret
79 ;
80 ; RV32IF-LABEL: fcopysign_fneg:
81 ; RV32IF: # %bb.0:
82 ; RV32IF-NEXT: lui a2, 524288
83 ; RV32IF-NEXT: xor a1, a1, a2
84 ; RV32IF-NEXT: fmv.w.x ft0, a1
85 ; RV32IF-NEXT: fmv.w.x ft1, a0
86 ; RV32IF-NEXT: fsgnj.s ft0, ft1, ft0
87 ; RV32IF-NEXT: fmv.x.w a0, ft0
88 ; RV32IF-NEXT: ret
89 ;
90 ; RV64I-LABEL: fcopysign_fneg:
91 ; RV64I: # %bb.0:
92 ; RV64I-NEXT: not a1, a1
93 ; RV64I-NEXT: lui a2, 524288
94 ; RV64I-NEXT: and a1, a1, a2
95 ; RV64I-NEXT: addiw a2, a2, -1
96 ; RV64I-NEXT: and a0, a0, a2
97 ; RV64I-NEXT: or a0, a0, a1
98 ; RV64I-NEXT: ret
99 %1 = fneg float %b
100 %2 = call float @llvm.copysign.f32(float %a, float %1)
101 ret float %2
102 }