[X86] PR27502: Fix the LEA optimization pass.
authorAndrey Turetskiy <andrey.turetskiy@gmail.com>
Tue, 26 Apr 2016 12:18:12 +0000 (12:18 +0000)
committerAndrey Turetskiy <andrey.turetskiy@gmail.com>
Tue, 26 Apr 2016 12:18:12 +0000 (12:18 +0000)
Handle MachineBasicBlock as a memory displacement operand in the LEA optimization pass.

Differential Revision: http://reviews.llvm.org/D19409

llvm-svn: 267551

llvm/lib/Target/X86/X86OptimizeLEAs.cpp
llvm/test/CodeGen/X86/lea-opt-memop-check-1.ll [moved from llvm/test/CodeGen/X86/lea-opt-memop-check.ll with 99% similarity]
llvm/test/CodeGen/X86/lea-opt-memop-check-2.ll [new file with mode: 0644]

index 5a7b562..3c83f5d 100644 (file)
@@ -146,6 +146,9 @@ template <> struct DenseMapInfo<MemOpKey> {
     case MachineOperand::MO_MCSymbol:
       Hash = hash_combine(Hash, Val.Disp->getMCSymbol());
       break;
+    case MachineOperand::MO_MachineBasicBlock:
+      Hash = hash_combine(Hash, Val.Disp->getMBB());
+      break;
     default:
       llvm_unreachable("Invalid address displacement operand");
     }
@@ -185,7 +188,7 @@ static inline bool isIdenticalOp(const MachineOperand &MO1,
 #ifndef NDEBUG
 static bool isValidDispOp(const MachineOperand &MO) {
   return MO.isImm() || MO.isCPI() || MO.isJTI() || MO.isSymbol() ||
-         MO.isGlobal() || MO.isBlockAddress() || MO.isMCSymbol();
+         MO.isGlobal() || MO.isBlockAddress() || MO.isMCSymbol() || MO.isMBB();
 }
 #endif
 
@@ -203,7 +206,8 @@ static bool isSimilarDispOp(const MachineOperand &MO1,
          (MO1.isBlockAddress() && MO2.isBlockAddress() &&
           MO1.getBlockAddress() == MO2.getBlockAddress()) ||
          (MO1.isMCSymbol() && MO2.isMCSymbol() &&
-          MO1.getMCSymbol() == MO2.getMCSymbol());
+          MO1.getMCSymbol() == MO2.getMCSymbol()) ||
+         (MO1.isMBB() && MO2.isMBB() && MO1.getMBB() == MO2.getMBB());
 }
 
 static inline bool isLEA(const MachineInstr &MI) {
@@ -1,4 +1,3 @@
-; REQUIRES: asserts
 ; RUN: llc < %s -march=x86 -mtriple=i686-pc-win32 | FileCheck %s
 
 ; PR26575
diff --git a/llvm/test/CodeGen/X86/lea-opt-memop-check-2.ll b/llvm/test/CodeGen/X86/lea-opt-memop-check-2.ll
new file mode 100644 (file)
index 0000000..f3fc95f
--- /dev/null
@@ -0,0 +1,21 @@
+; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=corei7 -relocation-model=pic | FileCheck %s
+
+; PR27502
+; UNREACHABLE: "Invalid address displacement operand"
+
+@buf = internal global [5 x i8*] zeroinitializer
+
+declare i32 @llvm.eh.sjlj.setjmp(i8*) nounwind
+
+define i32 @test() nounwind optsize {
+  %r = tail call i32 @llvm.eh.sjlj.setjmp(i8* bitcast ([5 x i8*]* @buf to i8*))
+  ret i32 %r
+; CHECK-LABEL: test:
+; CHECK:       leaq .LBB0_3(%rip), %r[[REG:[a-z]+]]
+; CHECK:       movq %r[[REG]], buf+8(%rip)
+; CHECK:       #EH_SjLj_Setup .LBB0_3
+; CHECK:       xorl %e[[REG]], %e[[REG]]
+; CHECK:       jmp .LBB0_2
+; CHECK-LABEL: .LBB0_3: # Block address taken
+; CHECK-LABEL: .LBB0_2:
+}