In thumb2 mode, add pc is unpredictable. Use add + mov pc instead (that is until...
authorEvan Cheng <evan.cheng@apple.com>
Tue, 28 Jul 2009 20:53:24 +0000 (20:53 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 28 Jul 2009 20:53:24 +0000 (20:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77364 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMISelLowering.h
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb.td
lib/Target/ARM/ARMInstrThumb2.td
test/CodeGen/Thumb2/thumb2-jtbl.ll

index afb0b69c54ea6786fc451e74c52c2eebf90e0e85..026018c7d73580a14b58f996b76b4a362e323fc2 100644 (file)
@@ -409,7 +409,6 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
   case ARMISD::tCALL:         return "ARMISD::tCALL";
   case ARMISD::BRCOND:        return "ARMISD::BRCOND";
   case ARMISD::BR_JT:         return "ARMISD::BR_JT";
-  case ARMISD::BR2_JT:        return "ARMISD::BR2_JT";
   case ARMISD::RET_FLAG:      return "ARMISD::RET_FLAG";
   case ARMISD::PIC_ADD:       return "ARMISD::PIC_ADD";
   case ARMISD::CMP:           return "ARMISD::CMP";
@@ -1712,17 +1711,15 @@ SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) {
   SDValue UId = DAG.getConstant(AFI->createJumpTableUId(), PTy);
   SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy);
   Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI, UId);
+  Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, PTy));
+  SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table);
   if (Subtarget->isThumb2()) {
     // Thumb2 uses a two-level jump. That is, it jumps into the jump table
     // which does another jump to the destination. This also makes it easier
     // to translate it to TBB / TBH later.
     // FIXME: This might not work if the function is extremely large.
-    return DAG.getNode(ARMISD::BR2_JT, dl, MVT::Other, Chain, Table, Index,
-                       JTI, UId);
+    return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI, UId);
   }
-
-  Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, PTy));
-  SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table);
   if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
     Addr = DAG.getLoad((MVT)MVT::i32, dl, Chain, Addr, NULL, 0);
     Chain = Addr.getValue(1);
index d0806fb9c1d7e8eb1160801e606d6f146ac1752e..42a19d45a6fbe3c97118d80d582cccae1442a71b 100644 (file)
@@ -40,7 +40,6 @@ namespace llvm {
       tCALL,        // Thumb function call.
       BRCOND,       // Conditional branch.
       BR_JT,        // Jumptable branch.
-      BR2_JT,       // Jumptable branch (2 level - jumptable entry is a jump).
       RET_FLAG,     // Return with a flag operand.
 
       PIC_ADD,      // Add with a PC operand and a PIC label.
index b4fb8a77d8644f0b2fa229c66247caa5c018d4bb..ab4ccd7d75fb64664f3457f0ea10db89362f7373 100644 (file)
@@ -33,9 +33,6 @@ def SDT_ARMBrcond  : SDTypeProfile<0, 2,
 def SDT_ARMBrJT    : SDTypeProfile<0, 3,
                                   [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
                                    SDTCisVT<2, i32>]>;
-def SDT_ARMBr2JT   : SDTypeProfile<0, 4,
-                                  [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
-                                   SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
 
 def SDT_ARMCmp     : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
 
@@ -75,9 +72,6 @@ def ARMbrcond        : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
 def ARMbrjt          : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
                               [SDNPHasChain]>;
 
-def ARMbr2jt         : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
-                              [SDNPHasChain]>;
-
 def ARMcmp           : SDNode<"ARMISD::CMP", SDT_ARMCmp,
                               [SDNPOutFlag]>;
 
index 07b7bf5cad0502e6fd9dfeedf393edf11d0579d0..542b8ba5e4d83dfa8c79ad5d378fb2be693aa2ad 100644 (file)
@@ -198,7 +198,7 @@ let isBranch = 1, isTerminator = 1 in {
 
   def tBR_JTr : T1JTI<(outs),
                       (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
-                      "mov pc, $target \n\t.align\t2\n$jt",
+                      "mov pc, $target\n\t.align\t2\n$jt",
                       [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>;
   }
 }
index b666b777f2b43964edfc26e468b5d5d7cd97337c..a77d93191d3f6178641362bbc92e6f4bc1b6fe5a 100644 (file)
@@ -1050,10 +1050,9 @@ def t2B   : T2XI<(outs), (ins brtarget:$target),
 
 let isNotDuplicable = 1, isIndirectBranch = 1 in
 def t2BR_JT :
-    T2JTI<(outs),
-          (ins GPR:$base, GPR:$idx, jt2block_operand:$jt, i32imm:$id),
-          "add.w pc, $base, $idx, lsl #2\n$jt",
-          [(ARMbr2jt GPR:$base, GPR:$idx, tjumptable:$jt, imm:$id)]>;
+    T2JTI<(outs), (ins GPR:$target, jt2block_operand:$jt, i32imm:$id),
+          "mov pc, $target\n$jt",
+          [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
 } // isBranch, isTerminator, isBarrier
 
 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
index a680df772a2b847899bae4dabad28c3513dc29b9..f84618e7ae883a8d85147082f71fff2796604c3e 100644 (file)
@@ -4,7 +4,7 @@
 define void @bar(i32 %n.u) {
 entry:
 ; CHECK: bar:
-; CHECK: add.w pc
+; CHECK: mov pc
 ; CHECK: b.w LBB1_2
 
     switch i32 %n.u, label %bb12 [i32 1, label %bb i32 2, label %bb6 i32 4, label %bb7 i32 5, label %bb8 i32 6, label %bb10 i32 7, label %bb1 i32 8, label %bb3 i32 9, label %bb4 i32 10, label %bb9 i32 11, label %bb2 i32 12, label %bb5 i32 13, label %bb11 ]