From 06f5b3661f31bfc93be294c78d667dfe4ecbc709 Mon Sep 17 00:00:00 2001 From: Stephen Tozer Date: Tue, 25 Feb 2025 09:24:14 +0000 Subject: [PATCH 1/2] [LLVM] Do not treat llvm.fake.use as a debug instruction The llvm.fake.use intrinsic is used to prevent certain values from being optimized out for the benefit of debug info; it is not, however, a debug or pseudo instruction itself and necessarily must not be treated as one, since its purpose is to act like a normal instruction. --- llvm/lib/IR/Instruction.cpp | 5 +- .../X86/fake-use-considered-when-sinking.ll | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 llvm/test/Transforms/SimplifyCFG/X86/fake-use-considered-when-sinking.ll diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 84d9306ca6700..7d43de982df0d 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -1233,10 +1233,7 @@ Instruction::getNextNonDebugInstruction(bool SkipPseudoOp) const { const Instruction * Instruction::getPrevNonDebugInstruction(bool SkipPseudoOp) const { for (const Instruction *I = getPrevNode(); I; I = I->getPrevNode()) - if (!isa(I) && - !(SkipPseudoOp && isa(I)) && - !(isa(I) && - cast(I)->getIntrinsicID() == Intrinsic::fake_use)) + if (!isa(I) && !(SkipPseudoOp && isa(I))) return I; return nullptr; } diff --git a/llvm/test/Transforms/SimplifyCFG/X86/fake-use-considered-when-sinking.ll b/llvm/test/Transforms/SimplifyCFG/X86/fake-use-considered-when-sinking.ll new file mode 100644 index 0000000000000..81ca02839eaa6 --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/X86/fake-use-considered-when-sinking.ll @@ -0,0 +1,67 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -p="simplifycfg" -S < %s | FileCheck %s + +;; Verify that fake uses are not ignored when sinking instructions in +;; SimplifyCFG; when a fake use appears in only one incoming block they prevent +;; further sinking, and when identical fake uses appear on both sides they +;; are sunk normally. + +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 @foo(i1 %bool, ptr %p) { +; CHECK-LABEL: define void @foo( +; CHECK-SAME: i1 [[BOOL:%.*]], ptr [[P:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: br i1 [[BOOL]], label %[[IF_ELSE:.*]], label %[[IF_THEN:.*]] +; CHECK: [[COMMON_RET:.*]]: +; CHECK-NEXT: ret void +; CHECK: [[IF_THEN]]: +; CHECK-NEXT: store ptr [[P]], ptr [[P]], align 8 +; CHECK-NEXT: br label %[[COMMON_RET]] +; CHECK: [[IF_ELSE]]: +; CHECK-NEXT: store ptr [[P]], ptr [[P]], align 8 +; CHECK-NEXT: notail call void (...) @llvm.fake.use(ptr [[P]]) +; CHECK-NEXT: br label %[[COMMON_RET]] +; +entry: + br i1 %bool, label %if.else, label %if.then + +common.ret: ; preds = %if.else, %if.then + ret void + +if.then: ; preds = %entry + store ptr %p, ptr %p, align 8 + br label %common.ret + +if.else: ; preds = %entry + store ptr %p, ptr %p, align 8 + notail call void (...) @llvm.fake.use(ptr %p) + br label %common.ret +} + +define void @bar(i1 %bool, ptr %p, ptr %q) { +; CHECK-LABEL: define void @bar( +; CHECK-SAME: i1 [[BOOL:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: store ptr [[P]], ptr [[P]], align 8 +; CHECK-NEXT: notail call void (...) @llvm.fake.use(ptr [[P]]) +; CHECK-NEXT: ret void +; +entry: + br i1 %bool, label %if.else, label %if.then + +common.ret: ; preds = %if.else, %if.then + ret void + +if.then: ; preds = %entry + store ptr %p, ptr %p, align 8 + notail call void (...) @llvm.fake.use(ptr %p) + br label %common.ret + +if.else: ; preds = %entry + store ptr %p, ptr %p, align 8 + notail call void (...) @llvm.fake.use(ptr %p) + br label %common.ret +} + From 3b5863fd03452e1b3ef43031da5d81a3232c40bc Mon Sep 17 00:00:00 2001 From: Stephen Tozer Date: Tue, 25 Feb 2025 09:33:55 +0000 Subject: [PATCH 2/2] Remove unused test param --- .../SimplifyCFG/X86/fake-use-considered-when-sinking.ll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/Transforms/SimplifyCFG/X86/fake-use-considered-when-sinking.ll b/llvm/test/Transforms/SimplifyCFG/X86/fake-use-considered-when-sinking.ll index 81ca02839eaa6..63217315c978c 100644 --- a/llvm/test/Transforms/SimplifyCFG/X86/fake-use-considered-when-sinking.ll +++ b/llvm/test/Transforms/SimplifyCFG/X86/fake-use-considered-when-sinking.ll @@ -40,9 +40,9 @@ if.else: ; preds = %entry br label %common.ret } -define void @bar(i1 %bool, ptr %p, ptr %q) { +define void @bar(i1 %bool, ptr %p) { ; CHECK-LABEL: define void @bar( -; CHECK-SAME: i1 [[BOOL:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]]) { +; CHECK-SAME: i1 [[BOOL:%.*]], ptr [[P:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: store ptr [[P]], ptr [[P]], align 8 ; CHECK-NEXT: notail call void (...) @llvm.fake.use(ptr [[P]])