[llvm] [llvm][gvn-sink] Don't try to sink inline asm (PR #138414)
via llvm-commits
llvm-commits at lists.llvm.org
Sat May 3 10:03:15 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Paul Kirth (ilovepi)
<details>
<summary>Changes</summary>
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/Scalar/GVN.cpp#L2932
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/138414.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/GVNSink.cpp (+3)
- (added) llvm/test/Transforms/GVNSink/pr138345.ll (+51)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/GVNSink.cpp b/llvm/lib/Transforms/Scalar/GVNSink.cpp
index 2058df33ea331..40f7a61cb5717 100644
--- a/llvm/lib/Transforms/Scalar/GVNSink.cpp
+++ b/llvm/lib/Transforms/Scalar/GVNSink.cpp
@@ -548,6 +548,9 @@ class GVNSink {
if (isa<PHINode>(I) || I->isEHPad() || isa<AllocaInst>(I) ||
I->getType()->isTokenTy())
return true;
+ // Inline asm can't be sunk either.
+ if (auto *CB = dyn_cast<CallBase>(I); CB->isInlineAsm())
+ return true;
return false;
}
diff --git a/llvm/test/Transforms/GVNSink/pr138345.ll b/llvm/test/Transforms/GVNSink/pr138345.ll
new file mode 100644
index 0000000000000..1c9ff5936625f
--- /dev/null
+++ b/llvm/test/Transforms/GVNSink/pr138345.ll
@@ -0,0 +1,51 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; REQUIRES: x86-registered-target
+; RUN: opt -passes="gvn-sink" -S %s | FileCheck %s
+; RUN: opt -passes="gvn-sink,correlated-propagation" -S %s | FileCheck %s
+
+;; See https://github.com/llvm/llvm-project/issues/138345 for details.
+;; The program below used to crash due to taking the address of the inline asm.
+;; gvn-sink shouldn't do anything in this case, so test that the pass no longer
+;; generates invalid IR and no longer crashes.
+
+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"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @c(i64 %num, ptr %ptr) {
+; CHECK-LABEL: define void @c(
+; CHECK-SAME: i64 [[NUM:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: switch i64 [[NUM]], label %[[SW_EPILOG:.*]] [
+; CHECK-NEXT: i64 1, label %[[SW_BB:.*]]
+; CHECK-NEXT: i64 0, label %[[SW_BB1:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[SW_BB]]:
+; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[PTR]], align 1
+; CHECK-NEXT: call void asm sideeffect "", "r,r,~{dirflag},~{fpsr},~{flags}"(i8 [[TMP1]], ptr @c)
+; CHECK-NEXT: br label %[[SW_EPILOG]]
+; CHECK: [[SW_BB1]]:
+; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[PTR]], align 1
+; CHECK-NEXT: call void asm sideeffect "movdqu 0 [[XMM0:%.*]] \0A\09", "r,r,~{dirflag},~{fpsr},~{flags}"(i8 [[TMP2]], ptr @c)
+; CHECK-NEXT: br label %[[SW_EPILOG]]
+; CHECK: [[SW_EPILOG]]:
+; CHECK-NEXT: ret void
+;
+entry:
+ switch i64 %num, label %sw.epilog [
+ i64 1, label %sw.bb
+ i64 0, label %sw.bb1
+ ]
+
+sw.bb: ; preds = %entry
+ %1 = load i8, ptr %ptr, align 1
+ call void asm sideeffect "", "r,r,~{dirflag},~{fpsr},~{flags}"(i8 %1, ptr @c)
+ br label %sw.epilog
+
+sw.bb1: ; preds = %entry
+ %2 = load i8, ptr %ptr, align 1
+ call void asm sideeffect "movdqu 0 %xmm0 \0A\09", "r,r,~{dirflag},~{fpsr},~{flags}"(i8 %2, ptr @c)
+ br label %sw.epilog
+
+sw.epilog: ; preds = %sw.bb1, %sw.bb, %entry
+ ret void
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/138414
More information about the llvm-commits
mailing list