[PATCH] [IfCvt] Don't re-ifconvert blocks with unanalyzable terminators.

Ahmed Bougacha ahmed.bougacha at gmail.com
Fri Mar 20 17:24:05 PDT 2015


If we couldn't analyze a terminator (i.e., it's an indirectbr, or some other weirdness), we can't safely re-if-convert a predicated block, because we can't tell whether the predicated terminator can fallthrough (it does).

Currently, we would completely ignore the fallthrough successor.  In the added testcase, this means we used to generate:


```
	...
@ %entry:
	cmp	r5, #21
	ittt	ne
@ %cc1f:
	cmpne	r7, #42
@ %cc2t:
	strne.w	r5, [r8]
	movne	pc, r10
@ %cc1t:
	...

```
Whereas the successor of %cc1f was originally %bb1.  With the fix, we get the correct:


```
	...
@ %entry:
	cmp	r5, #21
	itt	eq
@ %cc1t:
	streq.w	r5, [r11]
	moveq	pc, r0
@ %cc1f:
	cmp	r7, #42
	itt	ne
@ %cc2t:
	strne.w	r5, [r8]
	movne	pc, r10
@ %bb1:
	...

```

I'll admit the testcase is very contrived, as usual for these parts.

Thanks!
-Ahmed

http://reviews.llvm.org/D8509

Files:
  lib/CodeGen/IfConversion.cpp
  test/CodeGen/ARM/ifcvt-iter-indbr.ll

Index: lib/CodeGen/IfConversion.cpp
===================================================================
--- lib/CodeGen/IfConversion.cpp
+++ lib/CodeGen/IfConversion.cpp
@@ -731,6 +731,12 @@
   if (BBI.Predicate.size() && !TII->SubsumesPredicate(Pred, BBI.Predicate))
     return false;
 
+  // If it is already predicated but we couldn't analyze its terminator, the
+  // latter might fallthrough, but we can't determine where to.
+  // Conservatively avoid if-converting again.
+  if (BBI.Predicate.size() && !BBI.IsBrAnalyzable)
+    return false;
+
   if (BBI.BrCond.size()) {
     if (!isTriangle)
       return false;
Index: test/CodeGen/ARM/ifcvt-iter-indbr.ll
===================================================================
--- /dev/null
+++ test/CodeGen/ARM/ifcvt-iter-indbr.ll
@@ -0,0 +1,56 @@
+; RUN: llc < %s -mtriple thumbv7s-apple-darwin  -asm-verbose=false | FileCheck %s
+
+declare i32 @foo(i32)
+declare i8* @bar(i32, i8*, i8*)
+
+; Verify that we don't try to iteratively re-ifconvert a block with a
+; (predicated) indirectbr terminator.
+; If we do, we would ignore its fallthrough successor.
+
+
+; CHECK-LABEL: test:
+; CHECK:       cmp {{.*}}, #21
+; CHECK-NEXT:  itt eq
+; CHECK-NEXT:  streq.w
+; CHECK-NEXT:  moveq pc
+; CHECK-NEXT: LBB{{[0-9_]+}}:
+; CHECK-NEXT:  cmp {{.*}}, #42
+; CHECK-NEXT:  itt ne
+; CHECK-NEXT:  strne.w
+; CHECK-NEXT:  movne pc
+; CHECK-NEXT: Ltmp
+; CHECK-NEXT: LBB0_2:
+; CHECK-NEXT:  movw r0, #1234
+; CHECK-NEXT:  b [[FOOCALL:LBB[0-9_]+]]
+; CHECK-NEXT: Ltmp
+; CHECK-NEXT: LBB{{[0-9_]+}}:
+; CHECK-NEXT:  movw r0, #4567
+; CHECK-NEXT: [[FOOCALL]]:
+; CHECK-NEXT:  blx _foo
+
+define i32 @test(i32 %a, i32 %a2, i32* %p, i32* %p2) {
+entry:
+  %dst1 = call i8* @bar(i32 1, i8* blockaddress(@test, %bb1), i8* blockaddress(@test, %bb2))
+  %dst2 = call i8* @bar(i32 2, i8* blockaddress(@test, %bb1), i8* blockaddress(@test, %bb2))
+  %dst3 = call i8* @bar(i32 3, i8* blockaddress(@test, %bb1), i8* blockaddress(@test, %bb2))
+  %cc1 = icmp eq i32 %a, 21
+  br i1 %cc1, label %cc1t, label %cc1f
+
+cc1t:
+  store i32 %a, i32* %p
+  indirectbr i8* %dst3, [label %bb1, label %bb2]
+
+cc1f:
+  %cc2 = icmp ne i32 %a2, 42
+  br i1 %cc2, label %cc2t, label %bb1
+cc2t:
+  store i32 %a, i32* %p2
+  indirectbr i8* %dst1, [label %bb1, label %bb2]
+
+bb1:
+  %ret_bb1 = call i32 @foo(i32 1234)
+  ret i32 %ret_bb1
+bb2:
+  %ret_bb2 = call i32 @foo(i32 4567)
+  ret i32 %ret_bb2
+}

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D8509.22400.patch
Type: text/x-patch
Size: 2427 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150321/ff250a8f/attachment.bin>


More information about the llvm-commits mailing list