[PATCH] D41385: [PowerPC] fix a bug in redundant compare elimination

Hiroshi Inoue via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 19 03:47:38 PST 2017


inouehrs created this revision.
inouehrs added reviewers: hfinkel, echristo, nemanjai, kbarton, jtony, lei, sfertile, syzaara, gyiu, stefanp.

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.
The reported problem happen in the following code sequence:

  if (a == -1) ...
  if (a == (uint16_t)-1) ...


https://reviews.llvm.org/D41385

Files:
  lib/Target/PowerPC/PPCMIPeephole.cpp
  test/CodeGen/PowerPC/cmp_elimination.ll


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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D41385.127483.patch
Type: text/x-patch
Size: 2720 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171219/f3fb7d61/attachment.bin>


More information about the llvm-commits mailing list