diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 9d6a3b40b91..4d30e7b50c7 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -750,13 +750,24 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, // If the input sign bit is known to be zero, or if none of the top bits // are demanded, turn this into an unsigned shift right. - if (KnownZero.intersects(SignBit) || (HighBits & ~NewMask) == HighBits) { + if (KnownZero.intersects(SignBit) || (HighBits & ~NewMask) == HighBits) return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, VT, Op.getOperand(0), Op.getOperand(1))); - } else if (KnownOne.intersects(SignBit)) { // New bits are known one. - KnownOne |= HighBits; + + int Log2 = NewMask.exactLogBase2(); + if (Log2 >= 0) { + // The bit must come from the sign. + SDValue NewSA = + TLO.DAG.getConstant(BitWidth - 1 - Log2, + Op.getOperand(1).getValueType()); + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, VT, + Op.getOperand(0), NewSA)); } + + if (KnownOne.intersects(SignBit)) + // New bits are known one. + KnownOne |= HighBits; } break; case ISD::SIGN_EXTEND_INREG: { diff --git a/test/CodeGen/PowerPC/rlwimi-and.ll b/test/CodeGen/PowerPC/rlwimi-and.ll index e20a13fec0f..7963249ddf8 100644 --- a/test/CodeGen/PowerPC/rlwimi-and.ll +++ b/test/CodeGen/PowerPC/rlwimi-and.ll @@ -28,12 +28,11 @@ codeRepl17: ; preds = %codeRepl4 store i16 %rvml38.sroa.0.0.insert.insert, i16* undef, align 2 unreachable +; FIXME: the SLWI could be folded into the RLWIMI to give a rotate of 8. ; CHECK: @test -; CHECK-DAG: slwi [[R1:[0-9]+]], -; CHECK-DAG: rlwinm [[R2:[0-9]+]], -; CHECK-DAG: srawi [[R3:[0-9]+]], [[R1]] -; CHECK-DAG: rlwinm [[R4:[0-9]+]], [[R3]], 0, 23, 23 -; CHECK: rlwimi [[R4]], [[R2]], 0, +; CHECK-DAG: slwi [[R1:[0-9]+]], {{[0-9]+}}, 31 +; CHECK-DAG: rlwinm [[R2:[0-9]+]], {{[0-9]+}}, 0, 31, 31 +; CHECK: rlwimi [[R2]], [[R1]], 9, 23, 23 codeRepl29: ; preds = %codeRepl1 unreachable diff --git a/test/CodeGen/SystemZ/shift-10.ll b/test/CodeGen/SystemZ/shift-10.ll index 3fd965745ed..46ed2180dfd 100644 --- a/test/CodeGen/SystemZ/shift-10.ll +++ b/test/CodeGen/SystemZ/shift-10.ll @@ -64,3 +64,15 @@ define i64 @f5(i32 %a) { %or = or i64 %shl, 7 ret i64 %or } + +; Test that SRA gets replaced with SRL if the sign bit is the only one +; that matters. +define i64 @f6(i64 %a) { +; CHECK-LABEL: f6: +; CHECK: risbg %r2, %r2, 55, 183, 19 +; CHECK: br %r14 + %shl = shl i64 %a, 10 + %shr = ashr i64 %shl, 60 + %and = and i64 %shr, 256 + ret i64 %and +}