[SimplifyCFG] Allow merging invoke's with different attrs
Same logic as other callsites, if the attributes are intersectable, we
merge.
Closes #111713
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 18d26aa..566ae2c 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -2779,7 +2779,7 @@
// including operand bundles.
const InvokeInst *II0 = Invokes.front();
for (auto *II : Invokes.drop_front())
- if (!II->isSameOperationAs(II0))
+ if (!II->isSameOperationAs(II0, Instruction::CompareUsingIntersectedAttrs))
return false;
// Can we theoretically form the data operands for the merged `invoke`?
@@ -2918,6 +2918,10 @@
for (BasicBlock *OrigSuccBB : successors(II->getParent()))
OrigSuccBB->removePredecessor(II->getParent());
BranchInst::Create(MergedInvoke->getParent(), II->getParent());
+ bool Success = MergedInvoke->tryIntersectAttributes(II);
+ assert(Success && "Merged invokes with incompatible attributes");
+ // For NDEBUG Compile
+ (void)Success;
II->replaceAllUsesWith(MergedInvoke);
II->eraseFromParent();
++NumInvokesMerged;
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll b/llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll
index 0b676bd..95114ab 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll
@@ -1013,24 +1013,19 @@
; CHECK-LABEL: define void @t17_mismatched_attrs_okay_merge() personality ptr @__gxx_personality_v0 {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
-; CHECK-NEXT: br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
-; CHECK: [[IF_THEN0]]:
-; CHECK-NEXT: invoke void @simple_throw() #[[ATTR2:[0-9]+]]
-; CHECK-NEXT: to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
-; CHECK: [[INVOKE_CONT0]]:
-; CHECK-NEXT: unreachable
-; CHECK: [[LPAD]]:
+; CHECK-NEXT: br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
+; CHECK: [[LPAD:.*]]:
; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT: cleanup
; CHECK-NEXT: call void @destructor()
; CHECK-NEXT: resume { ptr, i32 } [[EH]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
-; CHECK-NEXT: br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
-; CHECK: [[IF_THEN1]]:
+; CHECK-NEXT: br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
+; CHECK: [[IF_THEN1_INVOKE]]:
; CHECK-NEXT: invoke void @simple_throw()
-; CHECK-NEXT: to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
-; CHECK: [[INVOKE_CONT2]]:
+; CHECK-NEXT: to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
+; CHECK: [[IF_THEN1_CONT]]:
; CHECK-NEXT: unreachable
; CHECK: [[IF_END]]:
; CHECK-NEXT: call void @sideeffect()
@@ -1070,24 +1065,19 @@
; CHECK-LABEL: define void @t17_mismatched_attrs_okay_merge_intersect() personality ptr @__gxx_personality_v0 {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
-; CHECK-NEXT: br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
-; CHECK: [[IF_THEN0]]:
-; CHECK-NEXT: invoke void @simple_throw() #[[ATTR3:[0-9]+]]
-; CHECK-NEXT: to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
-; CHECK: [[INVOKE_CONT0]]:
-; CHECK-NEXT: unreachable
-; CHECK: [[LPAD]]:
+; CHECK-NEXT: br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
+; CHECK: [[LPAD:.*]]:
; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT: cleanup
; CHECK-NEXT: call void @destructor()
; CHECK-NEXT: resume { ptr, i32 } [[EH]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
-; CHECK-NEXT: br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
-; CHECK: [[IF_THEN1]]:
-; CHECK-NEXT: invoke void @simple_throw() #[[ATTR2]]
-; CHECK-NEXT: to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
-; CHECK: [[INVOKE_CONT2]]:
+; CHECK-NEXT: br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
+; CHECK: [[IF_THEN1_INVOKE]]:
+; CHECK-NEXT: invoke void @simple_throw() #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
+; CHECK: [[IF_THEN1_CONT]]:
; CHECK-NEXT: unreachable
; CHECK: [[IF_END]]:
; CHECK-NEXT: call void @sideeffect()
@@ -1127,24 +1117,19 @@
; CHECK-LABEL: define void @t17_mismatched_attrs_okay_merge_intersect2() personality ptr @__gxx_personality_v0 {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
-; CHECK-NEXT: br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
-; CHECK: [[IF_THEN0]]:
-; CHECK-NEXT: invoke void @simple_throw() #[[ATTR2]]
-; CHECK-NEXT: to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
-; CHECK: [[INVOKE_CONT0]]:
-; CHECK-NEXT: unreachable
-; CHECK: [[LPAD]]:
+; CHECK-NEXT: br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
+; CHECK: [[LPAD:.*]]:
; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT: cleanup
; CHECK-NEXT: call void @destructor()
; CHECK-NEXT: resume { ptr, i32 } [[EH]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
-; CHECK-NEXT: br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
-; CHECK: [[IF_THEN1]]:
-; CHECK-NEXT: invoke void @simple_throw() #[[ATTR3]]
-; CHECK-NEXT: to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
-; CHECK: [[INVOKE_CONT2]]:
+; CHECK-NEXT: br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
+; CHECK: [[IF_THEN1_INVOKE]]:
+; CHECK-NEXT: invoke void @simple_throw() #[[ATTR2]]
+; CHECK-NEXT: to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
+; CHECK: [[IF_THEN1_CONT]]:
; CHECK-NEXT: unreachable
; CHECK: [[IF_END]]:
; CHECK-NEXT: call void @sideeffect()
@@ -1187,7 +1172,7 @@
; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT: br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
; CHECK: [[IF_THEN0]]:
-; CHECK-NEXT: invoke void @simple_throw() #[[ATTR4:[0-9]+]]
+; CHECK-NEXT: invoke void @simple_throw() #[[ATTR3:[0-9]+]]
; CHECK-NEXT: to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
; CHECK: [[INVOKE_CONT0]]:
; CHECK-NEXT: unreachable
@@ -2693,6 +2678,5 @@
; CHECK: attributes #[[ATTR0:[0-9]+]] = { noreturn }
; CHECK: attributes #[[ATTR1]] = { nomerge }
; CHECK: attributes #[[ATTR2]] = { memory(none) }
-; CHECK: attributes #[[ATTR3]] = { cold memory(none) }
-; CHECK: attributes #[[ATTR4]] = { strictfp }
+; CHECK: attributes #[[ATTR3]] = { strictfp }
;.