Skip to content

Commit 11e571e

Browse files
committedDec 20, 2017
[PowerPC] fix a bug in redundant compare elimination
This patch fixes a bug in the redundant compare elimination reported in https://reviews.llvm.org/rL320786 and re-enables the optimization. The redundant compare elimination assumes that we can replace signed comparison with unsigned comparison for the equality check. But due to the difference in the sign extension behavior we cannot change the opcode if the comparison is against an immediate and the most significant bit of the immediate is one. Differential Revision: https://reviews.llvm.org/D41385 llvm-svn: 321147
1 parent ab2ac29 commit 11e571e

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed
 

‎llvm/lib/Target/PowerPC/PPCMIPeephole.cpp

+13-5
Original file line numberDiff line numberDiff line change
@@ -1025,9 +1025,6 @@ bool PPCMIPeephole::eliminateRedundantTOCSaves(
10251025
// bge 0, .LBB0_4
10261026

10271027
bool PPCMIPeephole::eliminateRedundantCompare(void) {
1028-
// FIXME: this transformation is causing miscompiles. Disabling it for now
1029-
// until we can resolve the issue.
1030-
return false;
10311028
bool Simplified = false;
10321029

10331030
for (MachineBasicBlock &MBB2 : *MF) {
@@ -1087,10 +1084,21 @@ bool PPCMIPeephole::eliminateRedundantCompare(void) {
10871084
// we replace it with a signed comparison if the comparison
10881085
// to be merged is a signed comparison.
10891086
// In other cases of opcode mismatch, we cannot optimize this.
1090-
if (isEqOrNe(BI2) &&
1087+
1088+
// We cannot change opcode when comparing against an immediate
1089+
// if the most significant bit of the immediate is one
1090+
// due to the difference in sign extension.
1091+
auto CmpAgainstImmWithSignBit = [](MachineInstr *I) {
1092+
if (!I->getOperand(2).isImm())
1093+
return false;
1094+
int16_t Imm = (int16_t)I->getOperand(2).getImm();
1095+
return Imm < 0;
1096+
};
1097+
1098+
if (isEqOrNe(BI2) && !CmpAgainstImmWithSignBit(CMPI2) &&
10911099
CMPI1->getOpcode() == getSignedCmpOpCode(CMPI2->getOpcode()))
10921100
NewOpCode = CMPI1->getOpcode();
1093-
else if (isEqOrNe(BI1) &&
1101+
else if (isEqOrNe(BI1) && !CmpAgainstImmWithSignBit(CMPI1) &&
10941102
getSignedCmpOpCode(CMPI1->getOpcode()) == CMPI2->getOpcode())
10951103
NewOpCode = CMPI2->getOpcode();
10961104
else continue;

‎llvm/test/CodeGen/PowerPC/cmp_elimination.ll

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
; XFAIL: *
21
; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu | FileCheck %s
32
; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64le-unknown-linux-gnu | FileCheck %s
43

@@ -748,6 +747,37 @@ do.end:
748747
ret void
749748
}
750749

750+
define void @func29(i32 signext %a) {
751+
; We cannot merge two compares due to difference in sign extension behaviors.
752+
; equivalent C code example:
753+
; int a = .. ;
754+
; if (a == -1) dummy1();
755+
; if (a == (uint16_t)-1) dummy2();
756+
757+
; CHECK-LABEL: @func29
758+
; CHECK: cmp
759+
; CHECK: cmp
760+
; CHECK: blr
761+
entry:
762+
%cmp = icmp eq i32 %a, -1
763+
br i1 %cmp, label %if.then, label %if.else
764+
765+
if.then:
766+
tail call void @dummy1()
767+
br label %if.end3
768+
769+
if.else:
770+
%cmp1 = icmp eq i32 %a, 65535
771+
br i1 %cmp1, label %if.then2, label %if.end3
772+
773+
if.then2:
774+
tail call void @dummy2()
775+
br label %if.end3
776+
777+
if.end3:
778+
ret void
779+
}
780+
751781
declare void @dummy1()
752782
declare void @dummy2()
753783
declare void @dummy3()

0 commit comments

Comments
 (0)
Please sign in to comment.