// 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) {
// 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;
-; 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
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()