Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -4475,7 +4475,26 @@ CurDAG->SelectNodeTo(N, PPC::RLWINM8, MVT::i64, Ops); return true; } - // TODO - handle it with rldicl + rldicl + // Do nothing if it is 16-bit imm as the pattern in the .td file handle + // it well with "andi.". + if (isUInt<16>(Imm64)) + return false; + + // Optimize it with two rldicl instructions. + // 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. + Val = SDValue( + CurDAG->getMachineNode(PPC::RLDICL, dl, + MVT::i64, Val, getI64Imm(ME + 1, dl), + getI64Imm((MB + 63 - ME) & 63, dl)), 0); + SDValue Ops[] = { Val, getI64Imm(63 - ME, 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 @@ -15,8 +15,8 @@ define i64 @test2(i64 %a) { ; CHECK-LABEL: test2: ; CHECK: # %bb.0: -; CHECK-NEXT: li 4, -7 -; CHECK-NEXT: and 3, 3, 4 +; CHECK-NEXT: rldicl 3, 3, 61, 2 +; CHECK-NEXT: rotldi 3, 3, 3 ; CHECK-NEXT: blr %and = and i64 %a, -7 ret i64 %and @@ -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 Index: llvm/test/CodeGen/PowerPC/setcc-logic.ll =================================================================== --- llvm/test/CodeGen/PowerPC/setcc-logic.ll +++ llvm/test/CodeGen/PowerPC/setcc-logic.ll @@ -481,9 +481,9 @@ define i1 @or_icmps_const_1bit_diff(i64 %x) { ; CHECK-LABEL: or_icmps_const_1bit_diff: ; CHECK: # %bb.0: -; CHECK-NEXT: li 4, -5 ; CHECK-NEXT: addi 3, 3, -13 -; CHECK-NEXT: and 3, 3, 4 +; CHECK-NEXT: rldicl 3, 3, 61, 1 +; CHECK-NEXT: rotldi 3, 3, 3 ; CHECK-NEXT: cntlzd 3, 3 ; CHECK-NEXT: rldicl 3, 3, 58, 63 ; CHECK-NEXT: blr