Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -4466,10 +4466,23 @@ SDValue Ops[] = { Val, getI64Imm(0, dl), getI64Imm(MB - 32, dl), getI64Imm(ME - 32, dl) }; CurDAG->SelectNodeTo(N, PPC::RLWINM8, MVT::i64, Ops); - return true; } else { - // TODO - handle it with rldicl + rldicl + // MB ME MB+63-ME + // +----------------------+ +----------------------+ + // |0000001111111111111000| -> |0000000001111111111111| + // +----------------------+ +----------------------+ + // 0 64 0 64 + // Left rotate ME + 1 bit first and then, mask with (MB + 63 - ME, 63), + // and then, rotate back. + SH = ME + 1; + Val = SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, + MVT::i64, Val, getI64Imm(SH, dl), + getI64Imm((MB + 63 - ME) & 63, dl)), 0); + SDValue Ops[] = { Val, getI64Imm(64 - SH, dl), + getI64Imm(0, dl) }; + CurDAG->SelectNodeTo(N, PPC::RLDICL, MVT::i64, Ops); } + return true; } } Index: llvm/test/CodeGen/PowerPC/2016-04-17-combine.ll =================================================================== --- llvm/test/CodeGen/PowerPC/2016-04-17-combine.ll +++ llvm/test/CodeGen/PowerPC/2016-04-17-combine.ll @@ -7,8 +7,8 @@ %typ = type { i32, i32 } ; On release builds, it doesn't crash, spewing nonsense instead. -; To make sure it works, check that and is still alive. -; CHECK: and +; To make sure it works, check that rldicl is still alive. +; CHECK: rldicl ; Also, in release, it emits a COPY from a 32-bit register to ; a 64-bit register, which happens to be emitted as cror [!] ; by the confused CodeGen. Just to be sure, check there isn't one. Index: llvm/test/CodeGen/PowerPC/and-mask.ll =================================================================== --- llvm/test/CodeGen/PowerPC/and-mask.ll +++ llvm/test/CodeGen/PowerPC/and-mask.ll @@ -26,10 +26,8 @@ define i64 @test3(i64 %a) { ; CHECK-LABEL: test3: ; CHECK: # %bb.0: -; CHECK-NEXT: lis 4, 1023 -; CHECK-NEXT: ori 4, 4, 65535 -; CHECK-NEXT: sldi 4, 4, 22 -; CHECK-NEXT: and 3, 3, 4 +; CHECK-NEXT: rldicl 3, 3, 42, 38 +; CHECK-NEXT: rotldi 3, 3, 22 ; CHECK-NEXT: blr %and = and i64 %a, 281474972516352 ret i64 %and