ARM: recommit r237590: allow jump tables to be placed as constant islands.
The original version didn't properly account for the base register
being modified before the final jump, so caused miscompilations in
Chromium and LLVM. I've fixed this and tested with an LLVM self-host
(I don't have the means to build & test Chromium).
The general idea remains the same: in pathological cases jump tables
can be too far away from the instructions referencing them (like other
constants) so they need to be movable.
Should fix PR23627.
llvm-svn: 238680
diff --git a/llvm/test/CodeGen/ARM/jump-table-islands-split.ll b/llvm/test/CodeGen/ARM/jump-table-islands-split.ll
new file mode 100644
index 0000000..deba21b
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/jump-table-islands-split.ll
@@ -0,0 +1,52 @@
+; RUN: llc -mtriple=thumbv7s-apple-ios8.0 -o - %s | FileCheck %s
+
+declare void @foo(double)
+declare i32 @llvm.arm.space(i32, i32)
+
+; The constpool entry used to call @foo should be directly between where we want
+; the tbb and its table. Fortunately, the flow is simple enough that we can
+; eliminate the entry calculation (ADD) and use the ADR as the base.
+;
+; I'm hoping this won't be fragile, but if it does break the most likely fix is
+; adjusting the @llvm.arm.space call slightly. If this happens too many times
+; the test should probably be removed.
+define i32 @test_jumptable_not_adjacent(i1 %tst, i32 %sw, i32 %l) {
+; CHECK-LABEL: test_jumptable_not_adjacent:
+; CHECK: vldr {{d[0-9]+}}, [[DBL_CONST:LCPI[0-9]+_[0-9]+]]
+; [...]
+; CHECK: adr.w r[[BASE:[0-9]+]], [[JUMP_TABLE:LJTI[0-9]+_[0-9]+]]
+; CHECK-NOT: r[[BASE]]
+
+; CHECK: [[TBB_KEY:LCPI[0-9]+_[0-9]+]]:
+; CHECK-NEXT: tbb [r[[BASE]], {{r[0-9]+}}]
+
+; CHECK: [[DBL_CONST]]:
+; CHECK: .long
+; CHECK: .long
+; CHECK: [[JUMP_TABLE]]:
+; CHECK: .byte (LBB{{[0-9]+}}_{{[0-9]+}}-([[TBB_KEY]]+4)
+
+ br label %complex
+
+complex:
+ call void @foo(double 12345.0)
+ call i32 @llvm.arm.space(i32 970, i32 undef)
+ switch i32 %sw, label %second [ i32 0, label %other
+ i32 1, label %third
+ i32 2, label %end
+ i32 3, label %other ]
+
+second:
+ ret i32 43
+third:
+ ret i32 0
+
+other:
+ call void @bar()
+ unreachable
+
+end:
+ ret i32 42
+}
+
+declare void @bar()
diff --git a/llvm/test/CodeGen/ARM/jump-table-islands.ll b/llvm/test/CodeGen/ARM/jump-table-islands.ll
new file mode 100644
index 0000000..6b4f174
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/jump-table-islands.ll
@@ -0,0 +1,40 @@
+; RUN: llc -mtriple=armv7-apple-ios8.0 -o - %s | FileCheck %s
+
+%BigInt = type i5500
+
+define %BigInt @test_moved_jumptable(i1 %tst, i32 %sw, %BigInt %l) {
+; CHECK-LABEL: test_moved_jumptable:
+
+; CHECK: adr {{r[0-9]+}}, [[JUMP_TABLE:LJTI[0-9]+_[0-9]+]]
+; CHECK: b [[SKIP_TABLE:LBB[0-9]+_[0-9]+]]
+
+; CHECK: [[JUMP_TABLE]]:
+; CHECK: .data_region jt32
+; CHECK: .long LBB{{[0-9]+_[0-9]+}}-[[JUMP_TABLE]]
+
+; CHECK: [[SKIP_TABLE]]:
+; CHECK: add pc, {{r[0-9]+}}, {{r[0-9]+}}
+ br i1 %tst, label %simple, label %complex
+
+simple:
+ br label %end
+
+complex:
+ switch i32 %sw, label %simple [ i32 0, label %other
+ i32 1, label %third
+ i32 5, label %end
+ i32 6, label %other ]
+
+third:
+ ret %BigInt 0
+
+other:
+ call void @bar()
+ unreachable
+
+end:
+ %val = phi %BigInt [ %l, %complex ], [ -1, %simple ]
+ ret %BigInt %val
+}
+
+declare void @bar()
diff --git a/llvm/test/CodeGen/ARM/jumptable-label.ll b/llvm/test/CodeGen/ARM/jumptable-label.ll
index 49d6986..2ba90dc 100644
--- a/llvm/test/CodeGen/ARM/jumptable-label.ll
+++ b/llvm/test/CodeGen/ARM/jumptable-label.ll
@@ -2,8 +2,8 @@
; test that we print the label of a bb that is only used in a jump table.
-; CHECK: .long LBB0_2
-; CHECK: LBB0_2:
+; CHECK: .long [[JUMPTABLE_DEST:LBB[0-9]+_[0-9]+]]
+; CHECK: [[JUMPTABLE_DEST]]:
define i32 @calculate() {
entry:
diff --git a/llvm/test/CodeGen/Thumb2/constant-islands-jump-table.ll b/llvm/test/CodeGen/Thumb2/constant-islands-jump-table.ll
index 0dd7092..5ffe1f9 100644
--- a/llvm/test/CodeGen/Thumb2/constant-islands-jump-table.ll
+++ b/llvm/test/CodeGen/Thumb2/constant-islands-jump-table.ll
@@ -1,7 +1,7 @@
; RUN: llc < %s -mtriple=thumbv7-linux-gnueabihf -O1 %s -o - | FileCheck %s
; CHECK-LABEL: test_jump_table:
-; CHECK: b .LBB
+; CHECK: b{{.*}} .LBB
; CHECK-NOT: tbh
define i32 @test_jump_table(i32 %x, float %in) {
diff --git a/llvm/test/CodeGen/Thumb2/thumb2-tbh.ll b/llvm/test/CodeGen/Thumb2/thumb2-tbh.ll
index a5a5ed0..0761ed5 100644
--- a/llvm/test/CodeGen/Thumb2/thumb2-tbh.ll
+++ b/llvm/test/CodeGen/Thumb2/thumb2-tbh.ll
@@ -14,9 +14,19 @@
declare noalias i8* @calloc(i32, i32) nounwind
+; Jump tables are not anchored next to the TBB/TBH any more. Make sure the
+; correct address is still calculated (i.e. via a PC-relative symbol *at* the
+; TBB/TBH).
define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
; CHECK-LABEL: main:
-; CHECK: tbb
+; CHECK-NOT: adr {{r[0-9]+}}, LJTI
+; CHECK: [[PCREL_ANCHOR:LCPI[0-9]+_[0-9]+]]:
+; CHECK-NEXT: tbb [pc, {{r[0-9]+}}]
+
+; CHECK: LJTI0_0:
+; CHECK-NEXT: .data_region jt8
+; CHECK-NEXT: .byte (LBB{{[0-9]+_[0-9]+}}-([[PCREL_ANCHOR]]+4))/2
+
entry:
br label %bb42.i