diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index bfdd08b69c2d..62fac4bd9101 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -12604,9 +12604,10 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, (Op1VT == MVT::i32 || Op1VT == MVT::i16 || (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) { - // STBRX can only handle simple types. + // STBRX can only handle simple types and it makes no sense to store less + // two bytes in byte-reversed order. EVT mVT = cast(N)->getMemoryVT(); - if (mVT.isExtended()) + if (mVT.isExtended() || mVT.getSizeInBits() < 16) break; SDValue BSwapOp = N->getOperand(1).getOperand(0); diff --git a/llvm/test/CodeGen/PowerPC/pr39478.ll b/llvm/test/CodeGen/PowerPC/pr39478.ll new file mode 100644 index 000000000000..defb85608ad8 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/pr39478.ll @@ -0,0 +1,26 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=powerpc64le-unknown-unknown -verify-machineinstrs < %s | \ +; RUN: FileCheck %s +; RUN: llc -mtriple=powerpc64-unknown-unknown -verify-machineinstrs < %s | \ +; RUN: FileCheck %s + +define void @pr39478() { +; CHECK-LABEL: pr39478: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lwz 3, 0(3) +; CHECK-NEXT: stb 3, 0(3) +; CHECK-NEXT: blr +entry: + %tmp32 = load i64, i64* undef, align 8 + %tmp33 = load i32, i32* undef, align 4 + %tmp34 = and i32 %tmp33, -256 + %tmp35 = lshr i64 %tmp32, 32 + %tmp36 = shl nuw nsw i64 %tmp35, 24 + %tmp37 = trunc i64 %tmp36 to i32 + %tmp38 = call i32 @llvm.bswap.i32(i32 %tmp37) + %tmp39 = or i32 %tmp38, %tmp34 + store i32 %tmp39, i32* undef, align 4 + ret void +} + +declare i32 @llvm.bswap.i32(i32)