[PATCH] D12112: x32. Fixes jmp %reg in x32

João Porto via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 13:06:02 PDT 2015


jpp created this revision.
jpp added a subscriber: llvm-commits.
Herald added subscribers: dschuff, jfb.

http://reviews.llvm.org/D12112

Files:
  lib/Target/X86/X86ISelDAGToDAG.cpp
  test/CodeGen/X86/x32-indirectbr.ll

Index: test/CodeGen/X86/x32-indirectbr.ll
===================================================================
--- /dev/null
+++ test/CodeGen/X86/x32-indirectbr.ll
@@ -0,0 +1,56 @@
+; RUN: llc < %s -mtriple=x86_64-none-none-gnux32 -mcpu=generic | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-none-none-gnux32 -mcpu=generic -fast-isel | FileCheck %s
+; Bug 22859
+;
+; x32 pointers are 32-bits wide. x86-64 indirect branches use the full 64-bit
+; registers. Therefore, x32 CodeGen needs to zero extend indirectbr's target to
+; 64-bit.
+
+define i8 @test1() nounwind ssp {
+entry:
+  %0 = select i1 undef,                           ; <i8*> [#uses=1]
+              i8* blockaddress(@test1, %bb),
+              i8* blockaddress(@test1, %bb6)
+  indirectbr i8* %0, [label %bb, label %bb6]
+bb:                                               ; preds = %entry
+  ret i8 1
+
+bb6:                                              ; preds = %entry
+  ret i8 2
+}
+; CHECK: movl {{.*}}, %{{e|r}}[[REG:.[^d]*]]{{d?}}
+; CHECK: jmpq *%r[[REG]]
+
+define i32 @test2(i32 %idx) nounwind ssp {
+entry:
+  switch i32 %idx, label %abort [
+  i32 0, label %idx0
+  i32 1, label %idx1
+  i32 2, label %idx2
+  i32 3, label %idx3
+  i32 4, label %idx4
+  i32 5, label %idx5
+  i32 6, label %idx6
+  i32 7, label %idx7
+  ]
+idx0:                                             ; preds = %entry
+  ret i32 55
+idx1:                                             ; preds = %entry
+  ret i32 10
+idx2:                                             ; preds = %entry
+  ret i32 -1
+idx3:                                             ; preds = %entry
+  ret i32 1024
+idx4:                                             ; preds = %entry
+  ret i32 -1024
+idx5:                                             ; preds = %entry
+  ret i32 58
+idx6:                                             ; preds = %entry
+  ret i32 30
+idx7:                                             ; preds = %entry
+  ret i32 40
+abort:                                            ; preds = %entry
+  unreachable
+}
+; CHECK: movl {{.*}}, %{{e|r}}[[REG:.[^d]*]]{{d?}}
+; CHECK: jmpq *%r[[REG]]
Index: lib/Target/X86/X86ISelDAGToDAG.cpp
===================================================================
--- lib/Target/X86/X86ISelDAGToDAG.cpp
+++ lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -2277,6 +2277,20 @@
   switch (Opcode) {
   default:
     break;
+  case ISD::BRIND: {
+    if (Subtarget->isTarget64BitILP32() && !Subtarget->isTargetNaCl()) {
+      const SDValue &Target = Node->getOperand(1);
+      assert(Target.getSimpleValueType() == llvm::MVT::i32);
+      SDValue ZextTarget = CurDAG->getZExtOrTrunc(Target, dl, EVT(MVT::i64));
+      SDValue Brind = CurDAG->getNode(ISD::BRIND, dl, MVT::Other,
+                                      Node->getOperand(0), ZextTarget);
+      ReplaceUses(SDValue(Node, 0), Brind);
+      SelectCode(ZextTarget.getNode());
+      SelectCode(Brind.getNode());
+      return nullptr;
+    }
+    break;
+  }
   case ISD::INTRINSIC_W_CHAIN: {
     unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
     switch (IntNo) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12112.32441.patch
Type: text/x-patch
Size: 3117 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150818/8c73c64e/attachment.bin>


More information about the llvm-commits mailing list