Skip to content

Commit 71eda17

Browse files
authored
[Legalizer] Soften EXTRACT_ELEMENT on ppcf128 (#77412)
ppc_fp128 values are always split into two f64. Implement soften operation in soft-float mode to handle output f64 correctly.
1 parent 41dc04e commit 71eda17

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
6161
#endif
6262
report_fatal_error("Do not know how to soften the result of this "
6363
"operator!");
64-
64+
case ISD::EXTRACT_ELEMENT: R = SoftenFloatRes_EXTRACT_ELEMENT(N); break;
6565
case ISD::ARITH_FENCE: R = SoftenFloatRes_ARITH_FENCE(N); break;
6666
case ISD::MERGE_VALUES:R = SoftenFloatRes_MERGE_VALUES(N, ResNo); break;
6767
case ISD::BITCAST: R = SoftenFloatRes_BITCAST(N); break;
@@ -258,6 +258,15 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(SDNode *N) {
258258
}
259259
}
260260

261+
SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(SDNode *N) {
262+
SDValue Src = N->getOperand(0);
263+
assert(Src.getValueType() == MVT::ppcf128 &&
264+
"In floats only ppcf128 can be extracted by element!");
265+
return DAG.getNode(ISD::EXTRACT_ELEMENT, SDLoc(N),
266+
N->getValueType(0).changeTypeToInteger(),
267+
DAG.getBitcast(MVT::i128, Src), N->getOperand(1));
268+
}
269+
261270
SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo) {
262271
SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0));
263272
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N),

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
530530
SDValue SoftenFloatRes_BITCAST(SDNode *N);
531531
SDValue SoftenFloatRes_BUILD_PAIR(SDNode *N);
532532
SDValue SoftenFloatRes_ConstantFP(SDNode *N);
533+
SDValue SoftenFloatRes_EXTRACT_ELEMENT(SDNode *N);
533534
SDValue SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo);
534535
SDValue SoftenFloatRes_FABS(SDNode *N);
535536
SDValue SoftenFloatRes_FMINNUM(SDNode *N);

llvm/test/CodeGen/PowerPC/ppcsoftops.ll

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,68 @@ define dso_local zeroext i32 @func(double noundef %0, double noundef %1) #0 {
312312
ret i32 %9
313313
}
314314

315+
; To check ppc_fp128 soften without crash
316+
define zeroext i1 @ppcf128_soften(ppc_fp128 %a) #0 {
317+
; PPC-LABEL: ppcf128_soften:
318+
; PPC: # %bb.0: # %entry
319+
; PPC-NEXT: stwu 1, -16(1)
320+
; PPC-NEXT: stw 5, 8(1) # 4-byte Folded Spill
321+
; PPC-NEXT: mr 5, 4
322+
; PPC-NEXT: lwz 4, 8(1) # 4-byte Folded Reload
323+
; PPC-NEXT: stw 5, 12(1) # 4-byte Folded Spill
324+
; PPC-NEXT: mr 5, 3
325+
; PPC-NEXT: lwz 3, 12(1) # 4-byte Folded Reload
326+
; PPC-NEXT: # kill: def $r4 killed $r3
327+
; PPC-NEXT: # kill: def $r4 killed $r5
328+
; PPC-NEXT: xoris 4, 5, 65520
329+
; PPC-NEXT: or 4, 3, 4
330+
; PPC-NEXT: cntlzw 4, 4
331+
; PPC-NEXT: clrlwi 5, 5, 1
332+
; PPC-NEXT: or 3, 3, 5
333+
; PPC-NEXT: cntlzw 3, 3
334+
; PPC-NEXT: or 3, 3, 4
335+
; PPC-NEXT: srwi 3, 3, 5
336+
; PPC-NEXT: addi 1, 1, 16
337+
; PPC-NEXT: blr
338+
;
339+
; PPC64-LABEL: ppcf128_soften:
340+
; PPC64: # %bb.0: # %entry
341+
; PPC64-NEXT: li 4, 4095
342+
; PPC64-NEXT: rldic 4, 4, 52, 0
343+
; PPC64-NEXT: cmpld 7, 3, 4
344+
; PPC64-NEXT: mfcr 4 # cr7
345+
; PPC64-NEXT: rlwinm 4, 4, 31, 31, 31
346+
; PPC64-NEXT: clrldi 3, 3, 1
347+
; PPC64-NEXT: cmpldi 7, 3, 0
348+
; PPC64-NEXT: mfcr 3 # cr7
349+
; PPC64-NEXT: rlwinm 3, 3, 31, 31, 31
350+
; PPC64-NEXT: or 4, 3, 4
351+
; PPC64-NEXT: # implicit-def: $x3
352+
; PPC64-NEXT: mr 3, 4
353+
; PPC64-NEXT: clrldi 3, 3, 32
354+
; PPC64-NEXT: blr
355+
;
356+
; PPC64LE-LABEL: ppcf128_soften:
357+
; PPC64LE: # %bb.0: # %entry
358+
; PPC64LE-NEXT: li 3, 4095
359+
; PPC64LE-NEXT: rldic 3, 3, 52, 0
360+
; PPC64LE-NEXT: cmpd 4, 3
361+
; PPC64LE-NEXT: crmove 21, 2
362+
; PPC64LE-NEXT: clrldi. 3, 4, 1
363+
; PPC64LE-NEXT: crmove 20, 2
364+
; PPC64LE-NEXT: cror 20, 20, 21
365+
; PPC64LE-NEXT: li 4, 0
366+
; PPC64LE-NEXT: li 3, 1
367+
; PPC64LE-NEXT: isel 3, 3, 4, 20
368+
; PPC64LE-NEXT: blr
369+
entry:
370+
%fpclass = tail call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %a, i32 100)
371+
ret i1 %fpclass
372+
}
373+
315374
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
316375
declare double @llvm.fmuladd.f64(double, double, double) #1
376+
declare i1 @llvm.is.fpclass.ppcf128(ppc_fp128, i32 immarg) #1
317377

318378
attributes #0 = {"use-soft-float"="true" nounwind }
319379
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

0 commit comments

Comments
 (0)