BasicBlock *BB1 = BI->getSuccessor(0); // The true destination.
BasicBlock *BB2 = BI->getSuccessor(1); // The false destination
+ // If either of the blocks has it's address taken, then we can't do this fold,
+ // because the code we'd hoist would no longer run when we jump into the block
+ // by it's address.
+ if (BB1->hasAddressTaken() || BB2->hasAddressTaken())
+ return false;
+
BasicBlock::iterator BB1_Itr = BB1->begin();
BasicBlock::iterator BB2_Itr = BB2->begin();
loc2:
ret i32 42
}
+define i32 @test_inline_constraint_S_label_tailmerged(i1 %in) {
+; CHECK-LABEL: test_inline_constraint_S_label_tailmerged:
+ call void asm sideeffect "adr x0, $0", "S"(i8* blockaddress(@test_inline_constraint_S_label_tailmerged, %loc))
+; CHECK: adr x0, .Ltmp{{[0-9]+}}
+br i1 %in, label %loc, label %loc2
+loc:
+ br label %common.ret
+loc2:
+ br label %common.ret
+common.ret:
+ %common.retval = phi i32 [ 0, %loc ], [ 42, %loc2 ]
+ ret i32 %common.retval
+}
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -mem2reg -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
+
+define i32 @test_inline_constraint_S_label_tailmerged(i1 %in) {
+; CHECK-LABEL: @test_inline_constraint_S_label_tailmerged(
+; CHECK-NEXT: call void asm sideeffect "adr x0, $0", "S"(i8* blockaddress(@test_inline_constraint_S_label_tailmerged, [[COMMON_RET:%.*]]))
+; CHECK-NEXT: [[COMMON_RETVAL:%.*]] = select i1 [[IN:%.*]], i32 0, i32 42
+; CHECK-NEXT: br label [[COMMON_RET]]
+; CHECK: common.ret:
+; CHECK-NEXT: ret i32 [[COMMON_RETVAL]]
+;
+ call void asm sideeffect "adr x0, $0", "S"(i8* blockaddress(@test_inline_constraint_S_label_tailmerged, %loc))
+br i1 %in, label %loc, label %loc2
+loc:
+ br label %common.ret
+loc2:
+ br label %common.ret
+common.ret:
+ %common.retval = phi i32 [ 0, %loc ], [ 42, %loc2 ]
+ ret i32 %common.retval
+}