[llvm] b7a95ad - [SimplifyCFG] Don't sink loads/stores with swifterror pointers.
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 17 02:00:54 PDT 2023
Author: Florian Hahn
Date: 2023-08-17T09:59:07+01:00
New Revision: b7a95ad46724db0f6840ce3a910daf0530e7a913
URL: https://github.com/llvm/llvm-project/commit/b7a95ad46724db0f6840ce3a910daf0530e7a913
DIFF: https://github.com/llvm/llvm-project/commit/b7a95ad46724db0f6840ce3a910daf0530e7a913.diff
LOG: [SimplifyCFG] Don't sink loads/stores with swifterror pointers.
swifterror pointers can only be used as pointer operands of load & store
instructions (and as swifterror argument of a call). Sinking loads or
stores with swifterror pointer operands would require introducing a
select of of the pointer operands, which isn't allowed.
Check for this condition in canSinkInstructions.
Reviewed By: aschwaighofer
Differential Revision: https://reviews.llvm.org/D158083
Added:
Modified:
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/test/Transforms/SimplifyCFG/hoist-sink-swifterror-store.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 64b5a915042c52..aa8ac92cebe16c 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1808,10 +1808,19 @@ static bool canSinkInstructions(
}
const Instruction *I0 = Insts.front();
- for (auto *I : Insts)
+ for (auto *I : Insts) {
if (!I->isSameOperationAs(I0))
return false;
+ // swifterror pointers can only be used by a load or store; sinking a load
+ // or store would require introducing a select for the pointer operand,
+ // which isn't allowed for swifterror pointers.
+ if (isa<StoreInst>(I) && I->getOperand(1)->isSwiftError())
+ return false;
+ if (isa<LoadInst>(I) && I->getOperand(0)->isSwiftError())
+ return false;
+ }
+
// All instructions in Insts are known to be the same opcode. If they have a
// use, check that the only user is a PHI or in the same block as the
// instruction, because if a user is in the same block as an instruction we're
diff --git a/llvm/test/Transforms/SimplifyCFG/hoist-sink-swifterror-store.ll b/llvm/test/Transforms/SimplifyCFG/hoist-sink-swifterror-store.ll
index 213c04d54e9590..0c13f5703447a0 100644
--- a/llvm/test/Transforms/SimplifyCFG/hoist-sink-swifterror-store.ll
+++ b/llvm/test/Transforms/SimplifyCFG/hoist-sink-swifterror-store.ll
@@ -1,14 +1,27 @@
-; RUN: opt -passes='simplifycfg<sink-common-insts;hoist-common-insts>,verify' -disable-output %s
-
-; XFAIL: *
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -passes='simplifycfg<sink-common-insts;hoist-common-insts>,verify' -S %s | FileCheck %s
declare void @clobber1()
declare void @clobber2()
-; FIXME: currently simplifycfg tries to sink the stores to the exit block and
-; introduces a select for the pointer operand. This is not allowed for
-; swifterror pointers.
-define swiftcc void @sink_store(ptr %arg, ptr swifterror %arg1, i1 %c) {
+; Do not try to sink the stores to the exit block, as this requires introducing
+; a select for the pointer operand. This is not allowed for swifterror pointers.
+define swiftcc void @sink(ptr %arg, ptr swifterror %arg1, i1 %c) {
+; CHECK-LABEL: define swiftcc void @sink
+; CHECK-SAME: (ptr [[ARG:%.*]], ptr swifterror [[ARG1:%.*]], i1 [[C:%.*]]) {
+; CHECK-NEXT: bb:
+; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: call void @clobber1()
+; CHECK-NEXT: store ptr null, ptr [[ARG]], align 8
+; CHECK-NEXT: br label [[EXIT:%.*]]
+; CHECK: else:
+; CHECK-NEXT: call void @clobber2()
+; CHECK-NEXT: store ptr null, ptr [[ARG1]], align 8
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
bb:
br i1 %c, label %then, label %else
@@ -27,6 +40,21 @@ exit:
}
define swiftcc void @hoist_store(ptr %arg, ptr swifterror %arg1, i1 %c) {
+; CHECK-LABEL: define swiftcc void @hoist_store
+; CHECK-SAME: (ptr [[ARG:%.*]], ptr swifterror [[ARG1:%.*]], i1 [[C:%.*]]) {
+; CHECK-NEXT: bb:
+; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: store ptr null, ptr [[ARG]], align 8
+; CHECK-NEXT: call void @clobber1()
+; CHECK-NEXT: br label [[EXIT:%.*]]
+; CHECK: else:
+; CHECK-NEXT: store ptr null, ptr [[ARG1]], align 8
+; CHECK-NEXT: call void @clobber2()
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
bb:
br i1 %c, label %then, label %else
@@ -66,6 +94,22 @@ exit:
ret ptr %p
}
define swiftcc ptr @hoist_load(ptr %arg, ptr swifterror %arg1, i1 %c) {
+; CHECK-LABEL: define swiftcc ptr @hoist_load
+; CHECK-SAME: (ptr [[ARG:%.*]], ptr swifterror [[ARG1:%.*]], i1 [[C:%.*]]) {
+; CHECK-NEXT: bb:
+; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[L1:%.*]] = load ptr, ptr [[ARG]], align 8
+; CHECK-NEXT: call void @clobber1()
+; CHECK-NEXT: br label [[EXIT:%.*]]
+; CHECK: else:
+; CHECK-NEXT: [[L2:%.*]] = load ptr, ptr [[ARG1]], align 8
+; CHECK-NEXT: call void @clobber2()
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[L1]], [[THEN]] ], [ [[L2]], [[ELSE]] ]
+; CHECK-NEXT: ret ptr [[P]]
+;
bb:
br i1 %c, label %then, label %else
More information about the llvm-commits
mailing list