[PATCH] D29111: [SimplifyCFG] Do not sink and merge inline-asm instructions

Akira Hatanaka via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 24 19:00:37 PST 2017


ahatanak created this revision.

SimplifyCFG currently transforms the following IR

  if.then:
    %0 = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 %r6, i32 8)
    br label %if.end
  
  if.else:
    %1 = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 %r6, i32 6)
    br label %if.end

into this IR:

  %tobool = icmp eq i32 %c, 0
  %.sink = select i1 %tobool, i32 6, i32 8
  %0 = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 %r6, i32 %.sink)

This is bad because constraint "n" expects an immediate integer operand and merging the instructions causes a crash in the backend printing the following error message:

error: invalid operand for inline asm constraint 'n'

This patch fixes the crash by conservatively disabling the transformation when the instructions to be moved are inline-asm instructions.


https://reviews.llvm.org/D29111

Files:
  lib/Transforms/Utils/SimplifyCFG.cpp
  test/Transforms/SimplifyCFG/sink-common-code.ll


Index: test/Transforms/SimplifyCFG/sink-common-code.ll
===================================================================
--- test/Transforms/SimplifyCFG/sink-common-code.ll
+++ test/Transforms/SimplifyCFG/sink-common-code.ll
@@ -768,6 +768,30 @@
 ; CHECK-NOT: exact
 ; CHECK: }
 
+; Check that simplifycfg doesn't sink and merge inline-asm instructions.
+
+define i32 @test_inline_asm1(i32 %c, i32 %r6) {
+entry:
+  %tobool = icmp eq i32 %c, 0
+  br i1 %tobool, label %if.else, label %if.then
+
+if.then:
+  %0 = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 %r6, i32 8)
+  br label %if.end
+
+if.else:
+  %1 = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 %r6, i32 6)
+  br label %if.end
+
+if.end:
+  %r6.addr.0 = phi i32 [ %0, %if.then ], [ %1, %if.else ]
+  ret i32 %r6.addr.0
+}
+
+; CHECK-LABEL: @test_inline_asm1(
+; CHECK: call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 %r6, i32 8)
+; CHECK: call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 %r6, i32 6)
+
 declare i32 @call_target()
 
 define void @test_operand_bundles(i1 %cond, i32* %ptr) {
Index: lib/Transforms/Utils/SimplifyCFG.cpp
===================================================================
--- lib/Transforms/Utils/SimplifyCFG.cpp
+++ lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1436,6 +1436,12 @@
     if (isa<PHINode>(I) || I->isEHPad() || isa<AllocaInst>(I) ||
         I->getType()->isTokenTy())
       return false;
+
+    // Conservatively return false if I is an inline-asm instruction.
+    if (const auto *C = dyn_cast<CallInst>(I))
+      if (C->isInlineAsm())
+        return false;
+
     // Everything must have only one use too, apart from stores which
     // have no uses.
     if (!isa<StoreInst>(I) && !I->hasOneUse())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29111.85678.patch
Type: text/x-patch
Size: 1801 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170125/933d16d9/attachment.bin>


More information about the llvm-commits mailing list