Index: lib/Target/PowerPC/PPCMIPeephole.cpp =================================================================== --- lib/Target/PowerPC/PPCMIPeephole.cpp +++ lib/Target/PowerPC/PPCMIPeephole.cpp @@ -1025,9 +1025,6 @@ // bge 0, .LBB0_4 bool PPCMIPeephole::eliminateRedundantCompare(void) { - // FIXME: this transformation is causing miscompiles. Disabling it for now - // until we can resolve the issue. - return false; bool Simplified = false; for (MachineBasicBlock &MBB2 : *MF) { @@ -1087,10 +1084,21 @@ // we replace it with a signed comparison if the comparison // to be merged is a signed comparison. // In other cases of opcode mismatch, we cannot optimize this. - if (isEqOrNe(BI2) && + + // We cannot change opcode when comparing against an immediate + // if the most significant bit of the immediate is one + // due to the difference in sign extension. + auto CmpAgainstImmWithSignBit = [](MachineInstr *I) { + if (!I->getOperand(2).isImm()) + return false; + int16_t Imm = (int16_t)I->getOperand(2).getImm(); + return Imm < 0; + }; + + if (isEqOrNe(BI2) && !CmpAgainstImmWithSignBit(CMPI2) && CMPI1->getOpcode() == getSignedCmpOpCode(CMPI2->getOpcode())) NewOpCode = CMPI1->getOpcode(); - else if (isEqOrNe(BI1) && + else if (isEqOrNe(BI1) && !CmpAgainstImmWithSignBit(CMPI1) && getSignedCmpOpCode(CMPI1->getOpcode()) == CMPI2->getOpcode()) NewOpCode = CMPI2->getOpcode(); else continue; Index: test/CodeGen/PowerPC/cmp_elimination.ll =================================================================== --- test/CodeGen/PowerPC/cmp_elimination.ll +++ test/CodeGen/PowerPC/cmp_elimination.ll @@ -1,4 +1,3 @@ -; XFAIL: * ; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu | FileCheck %s ; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64le-unknown-linux-gnu | FileCheck %s @@ -748,6 +747,37 @@ ret void } +define void @func29(i32 signext %a) { +; We cannot merge two compares due to difference in sign extension behaviors. +; equivalent C code example: +; int a = .. ; +; if (a == -1) dummy1(); +; if (a == (uint16_t)-1) dummy2(); + +; CHECK-LABEL: @func29 +; CHECK: cmp +; CHECK: cmp +; CHECK: blr +entry: + %cmp = icmp eq i32 %a, -1 + br i1 %cmp, label %if.then, label %if.else + +if.then: + tail call void @dummy1() + br label %if.end3 + +if.else: + %cmp1 = icmp eq i32 %a, 65535 + br i1 %cmp1, label %if.then2, label %if.end3 + +if.then2: + tail call void @dummy2() + br label %if.end3 + +if.end3: + ret void +} + declare void @dummy1() declare void @dummy2() declare void @dummy3()