Skip to content

Commit 49c2f79

Browse files
committed
[llvm][gvn-sink] Don't try to sink inline asm
Fixes #138345. Before this patch, gvn-sink would try to sink inline assembly statements. Other GVN passes avoid them (see https://github.com/llvm/llvm-project/blob/b4fac94181c4cf17dbb7ecc2ae975712b0e4a6d1/llvm/lib/Transforms Similarly, gvn-sink should skip these instructions, since they are not safe to move. The test added is reduced from a failure when compiling Fuchsia. There were two distinct failure modes. One occurred when only running gvn-sink alone, but a different failure happened when running correlated-propagation afterwards.
1 parent 060f3f0 commit 49c2f79

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

llvm/lib/Transforms/Scalar/GVNSink.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,9 @@ class GVNSink {
548548
if (isa<PHINode>(I) || I->isEHPad() || isa<AllocaInst>(I) ||
549549
I->getType()->isTokenTy())
550550
return true;
551+
// Inline asm can't be sunk either.
552+
if (auto *CB = dyn_cast<CallBase>(I); CB->isInlineAsm())
553+
return true;
551554
return false;
552555
}
553556

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; REQUIRES: x86-registered-target
3+
; RUN: opt -passes="gvn-sink" -S %s | FileCheck %s
4+
; RUN: opt -passes="gvn-sink,correlated-propagation" -S %s | FileCheck %s
5+
6+
;; See https://github.com/llvm/llvm-project/issues/138345 for details.
7+
;; The program below used to crash due to taking the address of the inline asm.
8+
;; gvn-sink shouldn't do anything in this case, so test that the pass no longer
9+
;; generates invalid IR and no longer crashes.
10+
11+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
12+
target triple = "x86_64-unknown-linux-gnu"
13+
14+
define void @c(i64 %num, ptr %ptr) {
15+
; CHECK-LABEL: define void @c(
16+
; CHECK-SAME: i64 [[NUM:%.*]], ptr [[PTR:%.*]]) {
17+
; CHECK-NEXT: [[ENTRY:.*:]]
18+
; CHECK-NEXT: switch i64 [[NUM]], label %[[SW_EPILOG:.*]] [
19+
; CHECK-NEXT: i64 1, label %[[SW_BB:.*]]
20+
; CHECK-NEXT: i64 0, label %[[SW_BB1:.*]]
21+
; CHECK-NEXT: ]
22+
; CHECK: [[SW_BB]]:
23+
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[PTR]], align 1
24+
; CHECK-NEXT: call void asm sideeffect "", "r,r,~{dirflag},~{fpsr},~{flags}"(i8 [[TMP1]], ptr @c)
25+
; CHECK-NEXT: br label %[[SW_EPILOG]]
26+
; CHECK: [[SW_BB1]]:
27+
; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[PTR]], align 1
28+
; CHECK-NEXT: call void asm sideeffect "movdqu 0 [[XMM0:%.*]] \0A\09", "r,r,~{dirflag},~{fpsr},~{flags}"(i8 [[TMP2]], ptr @c)
29+
; CHECK-NEXT: br label %[[SW_EPILOG]]
30+
; CHECK: [[SW_EPILOG]]:
31+
; CHECK-NEXT: ret void
32+
;
33+
entry:
34+
switch i64 %num, label %sw.epilog [
35+
i64 1, label %sw.bb
36+
i64 0, label %sw.bb1
37+
]
38+
39+
sw.bb: ; preds = %entry
40+
%1 = load i8, ptr %ptr, align 1
41+
call void asm sideeffect "", "r,r,~{dirflag},~{fpsr},~{flags}"(i8 %1, ptr @c)
42+
br label %sw.epilog
43+
44+
sw.bb1: ; preds = %entry
45+
%2 = load i8, ptr %ptr, align 1
46+
call void asm sideeffect "movdqu 0 %xmm0 \0A\09", "r,r,~{dirflag},~{fpsr},~{flags}"(i8 %2, ptr @c)
47+
br label %sw.epilog
48+
49+
sw.epilog: ; preds = %sw.bb1, %sw.bb, %entry
50+
ret void
51+
}

0 commit comments

Comments
 (0)