From 45b149d2531948d2cc0e9d699a8e5371360a3bdf Mon Sep 17 00:00:00 2001 From: Tim Gymnich Date: Thu, 8 Aug 2024 02:51:04 +0200 Subject: [PATCH] [PowerPC] Respect endianness when bitcasting to fp128 (#95931) Fixes #92246 Match the behaviour of `bitcast v2i64 (BUILD_PAIR %lo %hi)` when encountering `bitcast fp128 (BUILD_PAIR %lo $hi)`. by inserting a missing swap of the arguments based on endianness. ### Current behaviour: **fp128** bitcast fp128 (BUILD_PAIR %lo $hi) => BUILD_FP128 %lo %hi BUILD_FP128 %lo %hi => MTVSRDD %hi %lo **v2i64** bitcast v2i64 (BUILD_PAIR %lo %hi) => BUILD_VECTOR %hi %lo BUILD_VECTOR %hi %lo => MTVSRDD %lo %hi (cherry picked from commit 408d82d352eb98e2d0a804c66d359cd7a49228fe) --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 14 +++++++++----- llvm/test/CodeGen/PowerPC/f128-aggregates.ll | 12 ++++++------ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index aaf0449a55387f..21cf4d9eeac173 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -9338,14 +9338,18 @@ SDValue PPCTargetLowering::LowerBITCAST(SDValue Op, SelectionDAG &DAG) const { SDLoc dl(Op); SDValue Op0 = Op->getOperand(0); + SDValue Lo = Op0.getOperand(0); + SDValue Hi = Op0.getOperand(1); + if ((Op.getValueType() != MVT::f128) || - (Op0.getOpcode() != ISD::BUILD_PAIR) || - (Op0.getOperand(0).getValueType() != MVT::i64) || - (Op0.getOperand(1).getValueType() != MVT::i64) || !Subtarget.isPPC64()) + (Op0.getOpcode() != ISD::BUILD_PAIR) || (Lo.getValueType() != MVT::i64) || + (Hi.getValueType() != MVT::i64) || !Subtarget.isPPC64()) return SDValue(); - return DAG.getNode(PPCISD::BUILD_FP128, dl, MVT::f128, Op0.getOperand(0), - Op0.getOperand(1)); + if (!Subtarget.isLittleEndian()) + std::swap(Lo, Hi); + + return DAG.getNode(PPCISD::BUILD_FP128, dl, MVT::f128, Lo, Hi); } static const SDValue *getNormalLoadInput(const SDValue &Op, bool &IsPermuted) { diff --git a/llvm/test/CodeGen/PowerPC/f128-aggregates.ll b/llvm/test/CodeGen/PowerPC/f128-aggregates.ll index b3d2457d31eebc..4be855e30ea1d4 100644 --- a/llvm/test/CodeGen/PowerPC/f128-aggregates.ll +++ b/llvm/test/CodeGen/PowerPC/f128-aggregates.ll @@ -283,7 +283,7 @@ define fp128 @testMixedAggregate([3 x i128] %a.coerce) { ; ; CHECK-BE-LABEL: testMixedAggregate: ; CHECK-BE: # %bb.0: # %entry -; CHECK-BE-NEXT: mtvsrdd v2, r8, r7 +; CHECK-BE-NEXT: mtvsrdd v2, r7, r8 ; CHECK-BE-NEXT: blr ; ; CHECK-P8-LABEL: testMixedAggregate: @@ -310,7 +310,7 @@ define fp128 @testMixedAggregate_02([4 x i128] %a.coerce) { ; ; CHECK-BE-LABEL: testMixedAggregate_02: ; CHECK-BE: # %bb.0: # %entry -; CHECK-BE-NEXT: mtvsrdd v2, r6, r5 +; CHECK-BE-NEXT: mtvsrdd v2, r5, r6 ; CHECK-BE-NEXT: blr ; ; CHECK-P8-LABEL: testMixedAggregate_02: @@ -344,7 +344,7 @@ define fp128 @testMixedAggregate_03([4 x i128] %sa.coerce) { ; CHECK-BE-LABEL: testMixedAggregate_03: ; CHECK-BE: # %bb.0: # %entry ; CHECK-BE-NEXT: mtvsrwa v2, r4 -; CHECK-BE-NEXT: mtvsrdd v3, r6, r5 +; CHECK-BE-NEXT: mtvsrdd v3, r5, r6 ; CHECK-BE-NEXT: xscvsdqp v2, v2 ; CHECK-BE-NEXT: xsaddqp v2, v3, v2 ; CHECK-BE-NEXT: mtvsrd v3, r9 @@ -467,7 +467,7 @@ define fp128 @testUnion_01([1 x i128] %a.coerce) { ; ; CHECK-BE-LABEL: testUnion_01: ; CHECK-BE: # %bb.0: # %entry -; CHECK-BE-NEXT: mtvsrdd v2, r4, r3 +; CHECK-BE-NEXT: mtvsrdd v2, r3, r4 ; CHECK-BE-NEXT: blr ; ; CHECK-P8-LABEL: testUnion_01: @@ -494,7 +494,7 @@ define fp128 @testUnion_02([1 x i128] %a.coerce) { ; ; CHECK-BE-LABEL: testUnion_02: ; CHECK-BE: # %bb.0: # %entry -; CHECK-BE-NEXT: mtvsrdd v2, r4, r3 +; CHECK-BE-NEXT: mtvsrdd v2, r3, r4 ; CHECK-BE-NEXT: blr ; ; CHECK-P8-LABEL: testUnion_02: @@ -521,7 +521,7 @@ define fp128 @testUnion_03([4 x i128] %a.coerce) { ; ; CHECK-BE-LABEL: testUnion_03: ; CHECK-BE: # %bb.0: # %entry -; CHECK-BE-NEXT: mtvsrdd v2, r8, r7 +; CHECK-BE-NEXT: mtvsrdd v2, r7, r8 ; CHECK-BE-NEXT: blr ; ; CHECK-P8-LABEL: testUnion_03: