@@ -180,6 +180,55 @@ define double @fsgnj_d(double %a, double %b) nounwind {
180180 ret double %1
181181}
182182
183+ ; This function performs extra work to ensure that
184+ ; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.
185+ define i32 @fneg_d (double %a , double %b ) nounwind {
186+ ; CHECKIFD-LABEL: fneg_d:
187+ ; CHECKIFD: # %bb.0:
188+ ; CHECKIFD-NEXT: fadd.d fa5, fa0, fa0
189+ ; CHECKIFD-NEXT: fneg.d fa4, fa5
190+ ; CHECKIFD-NEXT: feq.d a0, fa5, fa4
191+ ; CHECKIFD-NEXT: ret
192+ ;
193+ ; RV32I-LABEL: fneg_d:
194+ ; RV32I: # %bb.0:
195+ ; RV32I-NEXT: addi sp, sp, -16
196+ ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
197+ ; RV32I-NEXT: mv a2, a0
198+ ; RV32I-NEXT: mv a3, a1
199+ ; RV32I-NEXT: call __adddf3
200+ ; RV32I-NEXT: lui a3, 524288
201+ ; RV32I-NEXT: xor a3, a1, a3
202+ ; RV32I-NEXT: mv a2, a0
203+ ; RV32I-NEXT: call __eqdf2
204+ ; RV32I-NEXT: seqz a0, a0
205+ ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
206+ ; RV32I-NEXT: addi sp, sp, 16
207+ ; RV32I-NEXT: ret
208+ ;
209+ ; RV64I-LABEL: fneg_d:
210+ ; RV64I: # %bb.0:
211+ ; RV64I-NEXT: addi sp, sp, -16
212+ ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
213+ ; RV64I-NEXT: mv a1, a0
214+ ; RV64I-NEXT: call __adddf3
215+ ; RV64I-NEXT: li a1, -1
216+ ; RV64I-NEXT: slli a1, a1, 63
217+ ; RV64I-NEXT: xor a1, a0, a1
218+ ; RV64I-NEXT: call __eqdf2
219+ ; RV64I-NEXT: slli a0, a0, 32
220+ ; RV64I-NEXT: srli a0, a0, 32
221+ ; RV64I-NEXT: seqz a0, a0
222+ ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
223+ ; RV64I-NEXT: addi sp, sp, 16
224+ ; RV64I-NEXT: ret
225+ %1 = fadd double %a , %a
226+ %2 = fneg double %1
227+ %3 = fcmp oeq double %1 , %2
228+ %4 = zext i1 %3 to i32
229+ ret i32 %4
230+ }
231+
183232define double @fsgnjn_d (double %a , double %b ) nounwind {
184233; TODO: fsgnjn.s isn't selected on RV64 because DAGCombiner::visitBITCAST will
185234; convert (bitconvert (fneg x)) to a xor.
@@ -379,8 +428,8 @@ define double @fmsub_d(double %a, double %b, double %c) nounwind {
379428; RV32I-NEXT: mv s2, a2
380429; RV32I-NEXT: mv s3, a3
381430; RV32I-NEXT: mv a0, a4
382- ; RV32I-NEXT: lui a1, %hi(.LCPI11_0 )
383- ; RV32I-NEXT: addi a1, a1, %lo(.LCPI11_0 )
431+ ; RV32I-NEXT: lui a1, %hi(.LCPI12_0 )
432+ ; RV32I-NEXT: addi a1, a1, %lo(.LCPI12_0 )
384433; RV32I-NEXT: lw a2, 0(a1)
385434; RV32I-NEXT: lw a3, 4(a1)
386435; RV32I-NEXT: mv a1, a5
@@ -409,8 +458,8 @@ define double @fmsub_d(double %a, double %b, double %c) nounwind {
409458; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
410459; RV64I-NEXT: mv s0, a0
411460; RV64I-NEXT: mv s1, a1
412- ; RV64I-NEXT: lui a0, %hi(.LCPI11_0 )
413- ; RV64I-NEXT: ld a1, %lo(.LCPI11_0 )(a0)
461+ ; RV64I-NEXT: lui a0, %hi(.LCPI12_0 )
462+ ; RV64I-NEXT: ld a1, %lo(.LCPI12_0 )(a0)
414463; RV64I-NEXT: mv a0, a2
415464; RV64I-NEXT: call __adddf3
416465; RV64I-NEXT: li a1, -1
@@ -466,8 +515,8 @@ define double @fnmadd_d(double %a, double %b, double %c) nounwind {
466515; RV32I-NEXT: mv s0, a2
467516; RV32I-NEXT: mv s1, a3
468517; RV32I-NEXT: mv s2, a4
469- ; RV32I-NEXT: lui a2, %hi(.LCPI12_0 )
470- ; RV32I-NEXT: addi a2, a2, %lo(.LCPI12_0 )
518+ ; RV32I-NEXT: lui a2, %hi(.LCPI13_0 )
519+ ; RV32I-NEXT: addi a2, a2, %lo(.LCPI13_0 )
471520; RV32I-NEXT: lw s3, 0(a2)
472521; RV32I-NEXT: lw s4, 4(a2)
473522; RV32I-NEXT: mv s5, a5
@@ -511,8 +560,8 @@ define double @fnmadd_d(double %a, double %b, double %c) nounwind {
511560; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
512561; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
513562; RV64I-NEXT: mv s0, a1
514- ; RV64I-NEXT: lui a1, %hi(.LCPI12_0 )
515- ; RV64I-NEXT: ld s1, %lo(.LCPI12_0 )(a1)
563+ ; RV64I-NEXT: lui a1, %hi(.LCPI13_0 )
564+ ; RV64I-NEXT: ld s1, %lo(.LCPI13_0 )(a1)
516565; RV64I-NEXT: mv s2, a2
517566; RV64I-NEXT: mv a1, s1
518567; RV64I-NEXT: call __adddf3
@@ -580,8 +629,8 @@ define double @fnmadd_d_2(double %a, double %b, double %c) nounwind {
580629; RV32I-NEXT: mv a0, a2
581630; RV32I-NEXT: mv a1, a3
582631; RV32I-NEXT: mv s2, a4
583- ; RV32I-NEXT: lui a2, %hi(.LCPI13_0 )
584- ; RV32I-NEXT: addi a2, a2, %lo(.LCPI13_0 )
632+ ; RV32I-NEXT: lui a2, %hi(.LCPI14_0 )
633+ ; RV32I-NEXT: addi a2, a2, %lo(.LCPI14_0 )
585634; RV32I-NEXT: lw s3, 0(a2)
586635; RV32I-NEXT: lw s4, 4(a2)
587636; RV32I-NEXT: mv s5, a5
@@ -625,8 +674,8 @@ define double @fnmadd_d_2(double %a, double %b, double %c) nounwind {
625674; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
626675; RV64I-NEXT: mv s0, a0
627676; RV64I-NEXT: mv a0, a1
628- ; RV64I-NEXT: lui a1, %hi(.LCPI13_0 )
629- ; RV64I-NEXT: ld s1, %lo(.LCPI13_0 )(a1)
677+ ; RV64I-NEXT: lui a1, %hi(.LCPI14_0 )
678+ ; RV64I-NEXT: ld s1, %lo(.LCPI14_0 )(a1)
630679; RV64I-NEXT: mv s2, a2
631680; RV64I-NEXT: mv a1, s1
632681; RV64I-NEXT: call __adddf3
@@ -754,8 +803,8 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind {
754803; RV32I-NEXT: mv s0, a2
755804; RV32I-NEXT: mv s1, a3
756805; RV32I-NEXT: mv s2, a4
757- ; RV32I-NEXT: lui a2, %hi(.LCPI16_0 )
758- ; RV32I-NEXT: addi a3, a2, %lo(.LCPI16_0 )
806+ ; RV32I-NEXT: lui a2, %hi(.LCPI17_0 )
807+ ; RV32I-NEXT: addi a3, a2, %lo(.LCPI17_0 )
759808; RV32I-NEXT: lw a2, 0(a3)
760809; RV32I-NEXT: lw a3, 4(a3)
761810; RV32I-NEXT: mv s3, a5
@@ -782,8 +831,8 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind {
782831; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
783832; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
784833; RV64I-NEXT: mv s0, a1
785- ; RV64I-NEXT: lui a1, %hi(.LCPI16_0 )
786- ; RV64I-NEXT: ld a1, %lo(.LCPI16_0 )(a1)
834+ ; RV64I-NEXT: lui a1, %hi(.LCPI17_0 )
835+ ; RV64I-NEXT: ld a1, %lo(.LCPI17_0 )(a1)
787836; RV64I-NEXT: mv s1, a2
788837; RV64I-NEXT: call __adddf3
789838; RV64I-NEXT: li a1, -1
@@ -835,8 +884,8 @@ define double @fnmsub_d_2(double %a, double %b, double %c) nounwind {
835884; RV32I-NEXT: mv a0, a2
836885; RV32I-NEXT: mv a1, a3
837886; RV32I-NEXT: mv s2, a4
838- ; RV32I-NEXT: lui a2, %hi(.LCPI17_0 )
839- ; RV32I-NEXT: addi a3, a2, %lo(.LCPI17_0 )
887+ ; RV32I-NEXT: lui a2, %hi(.LCPI18_0 )
888+ ; RV32I-NEXT: addi a3, a2, %lo(.LCPI18_0 )
840889; RV32I-NEXT: lw a2, 0(a3)
841890; RV32I-NEXT: lw a3, 4(a3)
842891; RV32I-NEXT: mv s3, a5
@@ -865,8 +914,8 @@ define double @fnmsub_d_2(double %a, double %b, double %c) nounwind {
865914; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
866915; RV64I-NEXT: mv s0, a0
867916; RV64I-NEXT: mv a0, a1
868- ; RV64I-NEXT: lui a1, %hi(.LCPI17_0 )
869- ; RV64I-NEXT: ld a1, %lo(.LCPI17_0 )(a1)
917+ ; RV64I-NEXT: lui a1, %hi(.LCPI18_0 )
918+ ; RV64I-NEXT: ld a1, %lo(.LCPI18_0 )(a1)
870919; RV64I-NEXT: mv s1, a2
871920; RV64I-NEXT: call __adddf3
872921; RV64I-NEXT: li a1, -1
@@ -964,8 +1013,8 @@ define double @fmsub_d_contract(double %a, double %b, double %c) nounwind {
9641013; RV32I-NEXT: mv s2, a2
9651014; RV32I-NEXT: mv s3, a3
9661015; RV32I-NEXT: mv a0, a4
967- ; RV32I-NEXT: lui a1, %hi(.LCPI19_0 )
968- ; RV32I-NEXT: addi a1, a1, %lo(.LCPI19_0 )
1016+ ; RV32I-NEXT: lui a1, %hi(.LCPI20_0 )
1017+ ; RV32I-NEXT: addi a1, a1, %lo(.LCPI20_0 )
9691018; RV32I-NEXT: lw a2, 0(a1)
9701019; RV32I-NEXT: lw a3, 4(a1)
9711020; RV32I-NEXT: mv a1, a5
@@ -999,8 +1048,8 @@ define double @fmsub_d_contract(double %a, double %b, double %c) nounwind {
9991048; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
10001049; RV64I-NEXT: mv s0, a0
10011050; RV64I-NEXT: mv s1, a1
1002- ; RV64I-NEXT: lui a0, %hi(.LCPI19_0 )
1003- ; RV64I-NEXT: ld a1, %lo(.LCPI19_0 )(a0)
1051+ ; RV64I-NEXT: lui a0, %hi(.LCPI20_0 )
1052+ ; RV64I-NEXT: ld a1, %lo(.LCPI20_0 )(a0)
10041053; RV64I-NEXT: mv a0, a2
10051054; RV64I-NEXT: call __adddf3
10061055; RV64I-NEXT: mv s2, a0
@@ -1063,8 +1112,8 @@ define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind {
10631112; RV32I-NEXT: mv s0, a2
10641113; RV32I-NEXT: mv s1, a3
10651114; RV32I-NEXT: mv s2, a4
1066- ; RV32I-NEXT: lui a2, %hi(.LCPI20_0 )
1067- ; RV32I-NEXT: addi a2, a2, %lo(.LCPI20_0 )
1115+ ; RV32I-NEXT: lui a2, %hi(.LCPI21_0 )
1116+ ; RV32I-NEXT: addi a2, a2, %lo(.LCPI21_0 )
10681117; RV32I-NEXT: lw s3, 0(a2)
10691118; RV32I-NEXT: lw s4, 4(a2)
10701119; RV32I-NEXT: mv s5, a5
@@ -1118,8 +1167,8 @@ define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind {
11181167; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
11191168; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
11201169; RV64I-NEXT: mv s0, a1
1121- ; RV64I-NEXT: lui a1, %hi(.LCPI20_0 )
1122- ; RV64I-NEXT: ld s1, %lo(.LCPI20_0 )(a1)
1170+ ; RV64I-NEXT: lui a1, %hi(.LCPI21_0 )
1171+ ; RV64I-NEXT: ld s1, %lo(.LCPI21_0 )(a1)
11231172; RV64I-NEXT: mv s2, a2
11241173; RV64I-NEXT: mv a1, s1
11251174; RV64I-NEXT: call __adddf3
@@ -1192,8 +1241,8 @@ define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind {
11921241; RV32I-NEXT: mv s0, a2
11931242; RV32I-NEXT: mv s1, a3
11941243; RV32I-NEXT: mv s2, a4
1195- ; RV32I-NEXT: lui a2, %hi(.LCPI21_0 )
1196- ; RV32I-NEXT: addi a2, a2, %lo(.LCPI21_0 )
1244+ ; RV32I-NEXT: lui a2, %hi(.LCPI22_0 )
1245+ ; RV32I-NEXT: addi a2, a2, %lo(.LCPI22_0 )
11971246; RV32I-NEXT: lw s3, 0(a2)
11981247; RV32I-NEXT: lw s4, 4(a2)
11991248; RV32I-NEXT: mv s5, a5
@@ -1238,8 +1287,8 @@ define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind {
12381287; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
12391288; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
12401289; RV64I-NEXT: mv s0, a1
1241- ; RV64I-NEXT: lui a1, %hi(.LCPI21_0 )
1242- ; RV64I-NEXT: ld s1, %lo(.LCPI21_0 )(a1)
1290+ ; RV64I-NEXT: lui a1, %hi(.LCPI22_0 )
1291+ ; RV64I-NEXT: ld s1, %lo(.LCPI22_0 )(a1)
12431292; RV64I-NEXT: mv s2, a2
12441293; RV64I-NEXT: mv a1, s1
12451294; RV64I-NEXT: call __adddf3
0 commit comments