https://github.com/stephenduong1004 updated https://github.com/llvm/llvm-project/pull/214799
>From af80b038d6e4db08a734c892a7cf303a1a67aaa4 Mon Sep 17 00:00:00 2001 From: Stephen <[email protected]> Date: Fri, 7 Aug 2026 13:26:59 -0400 Subject: [PATCH 1/4] merge compatible unreachable calls --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 115 ++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 089892dc573f3..830ca49ad9caf 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -5794,6 +5794,118 @@ bool SimplifyCFGOpt::simplifyCleanupReturn(CleanupReturnInst *RI) { return false; } +static bool mergeCompatibleUnreachableCalls(BasicBlock *BB, + DomTreeUpdater *DTU) { + if (BB->size() != 2) + return false; + + auto *CI = dyn_cast<CallInst>(&BB->front()); + if (!CI || CI->arg_empty() || CI->isMustTailCall() || CI->isInlineAsm()) + return false; + + Function *Callee = CI->getCalledFunction(); + if (!Callee || !Callee->hasFnAttribute(Attribute::NoReturn)) + return false; + + Function *CurrentFn = BB->getParent(); + SmallVector<BasicBlock *, 8> BlocksToMerge; + BlocksToMerge.push_back(BB); + + for (User *U : Callee->users()) { + auto *OtherCI = dyn_cast<CallInst>(U); + if (!OtherCI || OtherCI == CI || OtherCI->getFunction() != CurrentFn) + continue; + + BasicBlock *OtherBB = OtherCI->getParent(); + if (OtherBB->size() != 2 || !isa<UnreachableInst>(OtherBB->getTerminator())) + continue; + + if (!OtherCI->isSameOperationAs(CI, + Instruction::CompareUsingIntersectedAttrs)) + continue; + + bool CanMerge = true; + for (unsigned i = 0; i < CI->arg_size(); ++i) { + if (CI->getArgOperand(i) != OtherCI->getArgOperand(i) && + !canReplaceOperandWithVariable(CI, i)) { + CanMerge = false; + break; + } + } + if (CanMerge) + BlocksToMerge.push_back(OtherBB); + } + + if (BlocksToMerge.size() < 2) + return false; + + BasicBlock *MergedBB = + BasicBlock::Create(BB->getContext(), "unreachable.merge", CurrentFn); + IRBuilder<> Builder(MergedBB); + + CallInst *MergedCall = cast<CallInst>(CI->clone()); + Builder.Insert(MergedCall); + Builder.CreateUnreachable(); + + DILocation *MergedLoc = nullptr; + SmallVector<DominatorTree::UpdateType, 8> Updates; + if (DTU) + Updates.reserve(2 * BlocksToMerge.size()); + + for (unsigned i = 0; i < MergedCall->arg_size(); ++i) { + bool NeedsPHI = false; + for (BasicBlock *OldBB : BlocksToMerge) { + auto *OldCI = cast<CallInst>(&OldBB->front()); + if (OldCI->getArgOperand(i) != CI->getArgOperand(i)) { + NeedsPHI = true; + break; + } + } + + if (NeedsPHI) { + PHINode *PN = + PHINode::Create(CI->getArgOperand(i)->getType(), BlocksToMerge.size(), + "", MergedCall->getIterator()); + for (BasicBlock *OldBB : BlocksToMerge) { + auto *OldCI = cast<CallInst>(&OldBB->front()); + PN->addIncoming(OldCI->getArgOperand(i), OldBB); + } + MergedCall->setArgOperand(i, PN); + } + } + + for (BasicBlock *OldBB : BlocksToMerge) { + auto *OldCI = cast<CallInst>(&OldBB->front()); + auto *OldUI = cast<UnreachableInst>(OldBB->getTerminator()); + + if (!MergedLoc) + MergedLoc = OldCI->getDebugLoc(); + else + MergedLoc = DebugLoc::getMergedLocation(MergedLoc, OldCI->getDebugLoc()); + + bool Success = MergedCall->tryIntersectAttributes(OldCI); + assert(Success && "Merged calls with incompatible attributes"); + (void)Success; + + if (!OldCI->use_empty()) + OldCI->replaceAllUsesWith(PoisonValue::get(OldCI->getType())); + OldCI->eraseFromParent(); + OldUI->eraseFromParent(); + + Builder.SetInsertPoint(OldBB); + Builder.CreateBr(MergedBB); + if (DTU) + Updates.push_back({DominatorTree::Insert, OldBB, MergedBB}); + } + + MergedCall->setDebugLoc(MergedLoc); + + if (DTU) + DTU->applyUpdates(Updates); + + return true; +} + // WARNING: keep in sync with InstCombinerImpl::visitUnreachableInst()! bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) { BasicBlock *BB = UI->getParent(); @@ -5835,6 +5947,9 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) { Changed = true; } + if (mergeCompatibleUnreachableCalls(BB, DTU)) + return true; + // If the unreachable instruction is the first in the block, take a gander // at all of the predecessors of this instruction, and simplify them. if (&BB->front() != UI) >From 88f4c4661752d275dace9bdded8e9e0abc824149 Mon Sep 17 00:00:00 2001 From: Stephen <[email protected]> Date: Fri, 14 Aug 2026 16:52:40 -0400 Subject: [PATCH 2/4] add support for nomerge --- clang/test/CodeGen/ubsan-trap-merge.c | 564 +++++++++++----------- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 6 +- 2 files changed, 287 insertions(+), 283 deletions(-) diff --git a/clang/test/CodeGen/ubsan-trap-merge.c b/clang/test/CodeGen/ubsan-trap-merge.c index b06420950d941..696d74a788d13 100644 --- a/clang/test/CodeGen/ubsan-trap-merge.c +++ b/clang/test/CodeGen/ubsan-trap-merge.c @@ -1,3 +1,4 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 // NOTE: Assertions have mostly been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 // The most important assertions are the attributes at the end of the file, which // show whether -ubsan-unique-traps and -fno-sanitize-merge attach 'nomerge' @@ -62,81 +63,81 @@ // TRAP-NOMERGE-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f( // TRAP-NOMERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // TRAP-NOMERGE-NEXT: [[ENTRY:.*:]] -// TRAP-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]] -// TRAP-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6:![0-9]+]] +// TRAP-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]] // TRAP-NOMERGE: [[TRAP]]: -// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // TRAP-NOMERGE: [[CONT]]: -// TRAP-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // TRAP-NOMERGE-NEXT: ret i32 [[TMP2]] // // HANDLER-NOMERGE-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f( // HANDLER-NOMERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // HANDLER-NOMERGE-NEXT: [[ENTRY:.*:]] -// HANDLER-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]] -// HANDLER-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6:![0-9]+]] +// HANDLER-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]] // HANDLER-NOMERGE: [[HANDLER_ADD_OVERFLOW]]: -// HANDLER-NOMERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP2]], i64 125) #[[ATTR4:[0-9]+]], !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP2]], i64 125) #[[ATTR4:[0-9]+]], !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-NOMERGE: [[CONT]]: -// HANDLER-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // HANDLER-NOMERGE-NEXT: ret i32 [[TMP3]] // // MINRT-NOMERGE-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f( // MINRT-NOMERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // MINRT-NOMERGE-NEXT: [[ENTRY:.*:]] -// MINRT-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]] -// MINRT-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6:![0-9]+]] +// MINRT-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]] // MINRT-NOMERGE: [[HANDLER_ADD_OVERFLOW]]: -// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4:[0-9]+]], !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4:[0-9]+]], !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-NOMERGE: [[CONT]]: -// MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // MINRT-NOMERGE-NEXT: ret i32 [[TMP2]] // // TRAP-MERGE-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f( // TRAP-MERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // TRAP-MERGE-NEXT: [[ENTRY:.*:]] -// TRAP-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]] -// TRAP-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// TRAP-MERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// TRAP-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6:![0-9]+]] +// TRAP-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// TRAP-MERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]] // TRAP-MERGE: [[TRAP]]: -// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], !nosanitize [[META2]] -// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], !nosanitize [[META6]] +// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META6]] // TRAP-MERGE: [[CONT]]: -// TRAP-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// TRAP-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // TRAP-MERGE-NEXT: ret i32 [[TMP2]] // // HANDLER-MERGE-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f( // HANDLER-MERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // HANDLER-MERGE-NEXT: [[ENTRY:.*:]] -// HANDLER-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]] -// HANDLER-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6:![0-9]+]] +// HANDLER-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]] // HANDLER-MERGE: [[HANDLER_ADD_OVERFLOW]]: -// HANDLER-MERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP2]], i64 125) #[[ATTR4:[0-9]+]], !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP2]], i64 125) #[[ATTR4:[0-9]+]], !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-MERGE: [[CONT]]: -// HANDLER-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // HANDLER-MERGE-NEXT: ret i32 [[TMP3]] // // MINRT-MERGE-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f( // MINRT-MERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // MINRT-MERGE-NEXT: [[ENTRY:.*:]] -// MINRT-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]] -// MINRT-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// MINRT-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// MINRT-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6:![0-9]+]] +// MINRT-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// MINRT-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]] // MINRT-MERGE: [[HANDLER_ADD_OVERFLOW]]: -// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4:[0-9]+]], !nosanitize [[META2]] -// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4:[0-9]+]], !nosanitize [[META6]] +// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-MERGE: [[CONT]]: -// MINRT-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// MINRT-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // MINRT-MERGE-NEXT: ret i32 [[TMP2]] // int f(int x) { @@ -185,81 +186,81 @@ int f(int x) { // TRAP-NOMERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g( // TRAP-NOMERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // TRAP-NOMERGE-NEXT: [[ENTRY:.*:]] -// TRAP-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-NOMERGE: [[TRAP]]: -// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // TRAP-NOMERGE: [[CONT]]: -// TRAP-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // TRAP-NOMERGE-NEXT: ret i32 [[TMP2]] // // HANDLER-NOMERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g( // HANDLER-NOMERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // HANDLER-NOMERGE-NEXT: [[ENTRY:.*:]] -// HANDLER-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-NOMERGE: [[HANDLER_ADD_OVERFLOW]]: -// HANDLER-NOMERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-NOMERGE: [[CONT]]: -// HANDLER-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // HANDLER-NOMERGE-NEXT: ret i32 [[TMP3]] // // MINRT-NOMERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g( // MINRT-NOMERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // MINRT-NOMERGE-NEXT: [[ENTRY:.*:]] -// MINRT-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-NOMERGE: [[HANDLER_ADD_OVERFLOW]]: -// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-NOMERGE: [[CONT]]: -// MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // MINRT-NOMERGE-NEXT: ret i32 [[TMP2]] // // TRAP-MERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g( // TRAP-MERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // TRAP-MERGE-NEXT: [[ENTRY:.*:]] -// TRAP-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// TRAP-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// TRAP-MERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// TRAP-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// TRAP-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// TRAP-MERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-MERGE: [[TRAP]]: -// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META6]] +// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META6]] // TRAP-MERGE: [[CONT]]: -// TRAP-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// TRAP-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // TRAP-MERGE-NEXT: ret i32 [[TMP2]] // // HANDLER-MERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g( // HANDLER-MERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // HANDLER-MERGE-NEXT: [[ENTRY:.*:]] -// HANDLER-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-MERGE: [[HANDLER_ADD_OVERFLOW]]: -// HANDLER-MERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-MERGE: [[CONT]]: -// HANDLER-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // HANDLER-MERGE-NEXT: ret i32 [[TMP3]] // // MINRT-MERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g( // MINRT-MERGE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // MINRT-MERGE-NEXT: [[ENTRY:.*:]] -// MINRT-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// MINRT-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// MINRT-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// MINRT-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// MINRT-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-MERGE: [[HANDLER_ADD_OVERFLOW]]: -// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-MERGE: [[CONT]]: -// MINRT-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// MINRT-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // MINRT-MERGE-NEXT: ret i32 [[TMP2]] // int g(int x) { @@ -315,133 +316,133 @@ int g(int x) { // TRAP-NOMERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h( // TRAP-NOMERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // TRAP-NOMERGE-NEXT: [[ENTRY:.*:]] -// TRAP-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-NOMERGE: [[TRAP]]: -// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // TRAP-NOMERGE: [[CONT]]: -// TRAP-NOMERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: br i1 [[TMP3]], label %[[TRAP1:.*]], label %[[CONT2:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: br i1 [[TMP3]], label %[[TRAP1:.*]], label %[[CONT2:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-NOMERGE: [[TRAP1]]: -// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // TRAP-NOMERGE: [[CONT2]]: -// TRAP-NOMERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // TRAP-NOMERGE-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP5]], i32 [[TMP4]]) // TRAP-NOMERGE-NEXT: ret i32 [[COND]] // // HANDLER-NOMERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h( // HANDLER-NOMERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // HANDLER-NOMERGE-NEXT: [[ENTRY:.*:]] -// HANDLER-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-NOMERGE: [[HANDLER_ADD_OVERFLOW]]: -// HANDLER-NOMERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-NOMERGE: [[CONT]]: -// HANDLER-NOMERGE-NEXT: [[TMP3:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: br i1 [[TMP4]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP3:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: br i1 [[TMP4]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-NOMERGE: [[HANDLER_ADD_OVERFLOW1]]: -// HANDLER-NOMERGE-NEXT: [[TMP5:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP5]], i64 129) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP5:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP5]], i64 129) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-NOMERGE: [[CONT2]]: -// HANDLER-NOMERGE-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP3]], 0, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP3]], 0, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // HANDLER-NOMERGE-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP7]], i32 [[TMP6]]) // HANDLER-NOMERGE-NEXT: ret i32 [[COND]] // // MINRT-NOMERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h( // MINRT-NOMERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // MINRT-NOMERGE-NEXT: [[ENTRY:.*:]] -// MINRT-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-NOMERGE: [[HANDLER_ADD_OVERFLOW]]: -// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-NOMERGE: [[CONT]]: -// MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-NOMERGE: [[HANDLER_ADD_OVERFLOW1]]: -// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-NOMERGE: [[CONT2]]: -// MINRT-NOMERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // MINRT-NOMERGE-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP5]], i32 [[TMP4]]) // MINRT-NOMERGE-NEXT: ret i32 [[COND]] // // TRAP-MERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h( // TRAP-MERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // TRAP-MERGE-NEXT: [[ENTRY:.*:]] -// TRAP-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// TRAP-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// TRAP-MERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// TRAP-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// TRAP-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// TRAP-MERGE-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-MERGE: [[TRAP]]: -// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META6]] +// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META6]] // TRAP-MERGE: [[CONT]]: -// TRAP-MERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]] -// TRAP-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] -// TRAP-MERGE-NEXT: br i1 [[TMP3]], label %[[TRAP]], label %[[CONT1:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// TRAP-MERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META6]] +// TRAP-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META6]] +// TRAP-MERGE-NEXT: br i1 [[TMP3]], label %[[TRAP]], label %[[CONT1:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-MERGE: [[CONT1]]: -// TRAP-MERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] -// TRAP-MERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// TRAP-MERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META6]] +// TRAP-MERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // TRAP-MERGE-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP5]], i32 [[TMP4]]) // TRAP-MERGE-NEXT: ret i32 [[COND]] // // HANDLER-MERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h( // HANDLER-MERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // HANDLER-MERGE-NEXT: [[ENTRY:.*:]] -// HANDLER-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-MERGE: [[HANDLER_ADD_OVERFLOW]]: -// HANDLER-MERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-MERGE: [[CONT]]: -// HANDLER-MERGE-NEXT: [[TMP3:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: br i1 [[TMP4]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP3:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: br i1 [[TMP4]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-MERGE: [[HANDLER_ADD_OVERFLOW1]]: -// HANDLER-MERGE-NEXT: [[TMP5:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP5]], i64 129) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP5:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP5]], i64 129) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-MERGE: [[CONT2]]: -// HANDLER-MERGE-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP3]], 0, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP3]], 0, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // HANDLER-MERGE-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP7]], i32 [[TMP6]]) // HANDLER-MERGE-NEXT: ret i32 [[COND]] // // MINRT-MERGE-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h( // MINRT-MERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // MINRT-MERGE-NEXT: [[ENTRY:.*:]] -// MINRT-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// MINRT-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// MINRT-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META6]] +// MINRT-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// MINRT-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-MERGE: [[HANDLER_ADD_OVERFLOW]]: -// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-MERGE: [[CONT]]: -// MINRT-MERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]] -// MINRT-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] -// MINRT-MERGE-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-MERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META6]] +// MINRT-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META6]] +// MINRT-MERGE-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-MERGE: [[HANDLER_ADD_OVERFLOW1]]: -// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-MERGE: [[CONT2]]: -// MINRT-MERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] -// MINRT-MERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// MINRT-MERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META6]] +// MINRT-MERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] // MINRT-MERGE-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP5]], i32 [[TMP4]]) // MINRT-MERGE-NEXT: ret i32 [[COND]] // @@ -544,201 +545,202 @@ int h(int x, int y) { // TRAP-NOMERGE-LABEL: define dso_local noundef i32 @m( // TRAP-NOMERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // TRAP-NOMERGE-NEXT: [[ENTRY:.*:]] -// TRAP-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: br i1 [[TMP1]], label %[[TRAP_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: br i1 [[TMP1]], label %[[TRAP_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-NOMERGE: [[TRAP_I]]: -// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // TRAP-NOMERGE: [[F_EXIT]]: -// TRAP-NOMERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: br i1 [[TMP3]], label %[[TRAP_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: br i1 [[TMP3]], label %[[TRAP_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-NOMERGE: [[TRAP_I2]]: -// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // TRAP-NOMERGE: [[G_EXIT]]: -// TRAP-NOMERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: br i1 [[TMP7]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: br i1 [[TMP7]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-NOMERGE: [[TRAP]]: -// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META6]] +// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // TRAP-NOMERGE: [[CONT]]: -// TRAP-NOMERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]] +// TRAP-NOMERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META6]] // TRAP-NOMERGE-NEXT: ret i32 [[TMP8]] // // HANDLER-NOMERGE-LABEL: define dso_local noundef i32 @m( // HANDLER-NOMERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // HANDLER-NOMERGE-NEXT: [[ENTRY:.*:]] -// HANDLER-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-NOMERGE: [[HANDLER_ADD_OVERFLOW_I]]: -// HANDLER-NOMERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1]], i64 [[TMP2]], i64 125) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1]], i64 [[TMP2]], i64 125) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-NOMERGE: [[F_EXIT]]: -// HANDLER-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: [[TMP4:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: br i1 [[TMP5]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: [[TMP4:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: br i1 [[TMP5]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-NOMERGE: [[HANDLER_ADD_OVERFLOW_I2]]: -// HANDLER-NOMERGE-NEXT: [[TMP6:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2]], i64 [[TMP6]], i64 127) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP6:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2]], i64 [[TMP6]], i64 127) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-NOMERGE: [[G_EXIT]]: -// HANDLER-NOMERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: [[TMP8:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP3]], i32 [[TMP7]]), !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: br i1 [[TMP9]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: [[TMP8:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP3]], i32 [[TMP7]]), !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: br i1 [[TMP9]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-NOMERGE: [[HANDLER_ADD_OVERFLOW]]: -// HANDLER-NOMERGE-NEXT: [[TMP10:%.*]] = zext i32 [[TMP3]] to i64, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: [[TMP11:%.*]] = zext i32 [[TMP7]] to i64, !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP10:%.*]] = zext i32 [[TMP3]] to i64, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: [[TMP11:%.*]] = zext i32 [[TMP7]] to i64, !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-NOMERGE: [[CONT]]: -// HANDLER-NOMERGE-NEXT: [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0, !nosanitize [[META2]] +// HANDLER-NOMERGE-NEXT: [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0, !nosanitize [[META6]] // HANDLER-NOMERGE-NEXT: ret i32 [[TMP12]] // // MINRT-NOMERGE-LABEL: define dso_local noundef i32 @m( // MINRT-NOMERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // MINRT-NOMERGE-NEXT: [[ENTRY:.*:]] -// MINRT-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-NOMERGE: [[HANDLER_ADD_OVERFLOW_I]]: -// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-NOMERGE: [[F_EXIT]]: -// MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-NOMERGE: [[HANDLER_ADD_OVERFLOW_I2]]: -// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-NOMERGE: [[G_EXIT]]: -// MINRT-NOMERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: br i1 [[TMP7]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: br i1 [[TMP7]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-NOMERGE: [[HANDLER_ADD_OVERFLOW]]: -// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-NOMERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-NOMERGE: [[CONT]]: -// MINRT-NOMERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]] +// MINRT-NOMERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META6]] // MINRT-NOMERGE-NEXT: ret i32 [[TMP8]] // // TRAP-MERGE-LABEL: define dso_local noundef i32 @m( // TRAP-MERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // TRAP-MERGE-NEXT: [[ENTRY:.*:]] -// TRAP-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]] -// TRAP-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// TRAP-MERGE-NEXT: br i1 [[TMP1]], label %[[TRAP_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] -// TRAP-MERGE: [[TRAP_I]]: -// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6]] +// TRAP-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// TRAP-MERGE-NEXT: br i1 [[TMP1]], label %[[UNREACHABLE_MERGE:.*]], label %[[F_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-MERGE: [[F_EXIT]]: -// TRAP-MERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]] -// TRAP-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] -// TRAP-MERGE-NEXT: br i1 [[TMP3]], label %[[TRAP_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] -// TRAP-MERGE: [[TRAP_I2]]: -// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-MERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META6]] +// TRAP-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META6]] +// TRAP-MERGE-NEXT: br i1 [[TMP3]], label %[[UNREACHABLE_MERGE]], label %[[G_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-MERGE: [[G_EXIT]]: -// TRAP-MERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] -// TRAP-MERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] -// TRAP-MERGE-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META2]] -// TRAP-MERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META2]] -// TRAP-MERGE-NEXT: br i1 [[TMP7]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] -// TRAP-MERGE: [[TRAP]]: -// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// TRAP-MERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] +// TRAP-MERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META6]] +// TRAP-MERGE-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META6]] +// TRAP-MERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META6]] +// TRAP-MERGE-NEXT: br i1 [[TMP7]], label %[[UNREACHABLE_MERGE]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // TRAP-MERGE: [[CONT]]: -// TRAP-MERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]] +// TRAP-MERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META6]] // TRAP-MERGE-NEXT: ret i32 [[TMP8]] +// TRAP-MERGE: [[UNREACHABLE_MERGE]]: +// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META6]] +// TRAP-MERGE-NEXT: unreachable // // HANDLER-MERGE-LABEL: define dso_local noundef i32 @m( // HANDLER-MERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // HANDLER-MERGE-NEXT: [[ENTRY:.*:]] -// HANDLER-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-MERGE: [[HANDLER_ADD_OVERFLOW_I]]: -// HANDLER-MERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1]], i64 [[TMP2]], i64 125) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1]], i64 [[TMP2]], i64 125) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-MERGE: [[F_EXIT]]: -// HANDLER-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: [[TMP4:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: br i1 [[TMP5]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: [[TMP4:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: br i1 [[TMP5]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-MERGE: [[HANDLER_ADD_OVERFLOW_I2]]: -// HANDLER-MERGE-NEXT: [[TMP6:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2]], i64 [[TMP6]], i64 127) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP6:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2]], i64 [[TMP6]], i64 127) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-MERGE: [[G_EXIT]]: -// HANDLER-MERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: [[TMP8:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP3]], i32 [[TMP7]]), !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: br i1 [[TMP9]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: [[TMP8:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP3]], i32 [[TMP7]]), !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: br i1 [[TMP9]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // HANDLER-MERGE: [[HANDLER_ADD_OVERFLOW]]: -// HANDLER-MERGE-NEXT: [[TMP10:%.*]] = zext i32 [[TMP3]] to i64, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: [[TMP11:%.*]] = zext i32 [[TMP7]] to i64, !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR4]], !nosanitize [[META2]] -// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP10:%.*]] = zext i32 [[TMP3]] to i64, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: [[TMP11:%.*]] = zext i32 [[TMP7]] to i64, !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR4]], !nosanitize [[META6]] +// HANDLER-MERGE-NEXT: unreachable, !nosanitize [[META6]] // HANDLER-MERGE: [[CONT]]: -// HANDLER-MERGE-NEXT: [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0, !nosanitize [[META2]] +// HANDLER-MERGE-NEXT: [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0, !nosanitize [[META6]] // HANDLER-MERGE-NEXT: ret i32 [[TMP12]] // // MINRT-MERGE-LABEL: define dso_local noundef i32 @m( // MINRT-MERGE-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // MINRT-MERGE-NEXT: [[ENTRY:.*:]] -// MINRT-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]] -// MINRT-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// MINRT-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-MERGE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META6]] +// MINRT-MERGE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META6]] +// MINRT-MERGE-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-MERGE: [[HANDLER_ADD_OVERFLOW_I]]: -// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-MERGE: [[F_EXIT]]: -// MINRT-MERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]] -// MINRT-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] -// MINRT-MERGE-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-MERGE-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META6]] +// MINRT-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META6]] +// MINRT-MERGE-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-MERGE: [[HANDLER_ADD_OVERFLOW_I2]]: -// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-MERGE: [[G_EXIT]]: -// MINRT-MERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] -// MINRT-MERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] -// MINRT-MERGE-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META2]] -// MINRT-MERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META2]] -// MINRT-MERGE-NEXT: br i1 [[TMP7]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT-MERGE-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META6]] +// MINRT-MERGE-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META6]] +// MINRT-MERGE-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META6]] +// MINRT-MERGE-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META6]] +// MINRT-MERGE-NEXT: br i1 [[TMP7]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF7]], !nosanitize [[META6]] // MINRT-MERGE: [[HANDLER_ADD_OVERFLOW]]: -// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] -// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META2]] +// MINRT-MERGE-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META6]] +// MINRT-MERGE-NEXT: unreachable, !nosanitize [[META6]] // MINRT-MERGE: [[CONT]]: -// MINRT-MERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]] +// MINRT-MERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META6]] // MINRT-MERGE-NEXT: ret i32 [[TMP8]] // int m(int x, int y) { return f(x) + g(y); } -// TRAP-MERGE: attributes #[[ATTR4]] = { noreturn nounwind } -// HANDLER-MERGE: attributes #[[ATTR4]] = { noreturn nounwind } -// MINRT-MERGE: attributes #[[ATTR4]] = { noreturn nounwind } -// TRAP-NOMERGE: attributes #[[ATTR4]] = { nomerge noreturn nounwind } -// HANDLER-NOMERGE: attributes #[[ATTR4]] = { nomerge noreturn nounwind } -// MINRT-NOMERGE: attributes #[[ATTR4]] = { nomerge noreturn nounwind } -// TRAP-MERGE: [[PROF3]] = !{!"branch_weights", i32 1, i32 1048575} -// HANDLER-MERGE: [[PROF3]] = !{!"branch_weights", i32 1, i32 1048575} -// MINRT-MERGE: [[PROF3]] = !{!"branch_weights", i32 1, i32 1048575} -// TRAP-NOMERGE: [[PROF3]] = !{!"branch_weights", i32 1, i32 1048575} -// HANDLER-NOMERGE: [[PROF3]] = !{!"branch_weights", i32 1, i32 1048575} -// MINRT-NOMERGE: [[PROF3]] = !{!"branch_weights", i32 1, i32 1048575} +//. +// TRAP-NOMERGE: [[META6]] = !{} +// TRAP-NOMERGE: [[PROF7]] = !{!"branch_weights", i32 1, i32 1048575} +//. +// HANDLER-NOMERGE: [[META6]] = !{} +// HANDLER-NOMERGE: [[PROF7]] = !{!"branch_weights", i32 1, i32 1048575} +//. +// MINRT-NOMERGE: [[META6]] = !{} +// MINRT-NOMERGE: [[PROF7]] = !{!"branch_weights", i32 1, i32 1048575} +//. +// TRAP-MERGE: [[META6]] = !{} +// TRAP-MERGE: [[PROF7]] = !{!"branch_weights", i32 1, i32 1048575} +//. +// HANDLER-MERGE: [[META6]] = !{} +// HANDLER-MERGE: [[PROF7]] = !{!"branch_weights", i32 1, i32 1048575} +//. +// MINRT-MERGE: [[META6]] = !{} +// MINRT-MERGE: [[PROF7]] = !{!"branch_weights", i32 1, i32 1048575} +//. diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 830ca49ad9caf..ce2006eaf94b8 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -5800,7 +5800,8 @@ static bool mergeCompatibleUnreachableCalls(BasicBlock *BB, return false; auto *CI = dyn_cast<CallInst>(&BB->front()); - if (!CI || CI->arg_empty() || CI->isMustTailCall() || CI->isInlineAsm()) + if (!CI || CI->arg_empty() || CI->isMustTailCall() || CI->isInlineAsm() || + CI->cannotMerge() || CI->isConvergent()) return false; Function *Callee = CI->getCalledFunction(); @@ -5813,7 +5814,8 @@ static bool mergeCompatibleUnreachableCalls(BasicBlock *BB, for (User *U : Callee->users()) { auto *OtherCI = dyn_cast<CallInst>(U); - if (!OtherCI || OtherCI == CI || OtherCI->getFunction() != CurrentFn) + if (!OtherCI || OtherCI == CI || OtherCI->getFunction() != CurrentFn || + OtherCI->cannotMerge() || OtherCI->isConvergent()) continue; BasicBlock *OtherBB = OtherCI->getParent(); >From 40e89b8eab0c011e91d1b397ed657d23f350588f Mon Sep 17 00:00:00 2001 From: Stephen <[email protected]> Date: Mon, 17 Aug 2026 11:47:24 -0400 Subject: [PATCH 3/4] fix hackme --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 22 ++++++++++++------- llvm/test/Transforms/PhaseOrdering/dae-dce.ll | 14 +++++++----- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index ce2006eaf94b8..004defcbf6257 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -5827,13 +5827,16 @@ static bool mergeCompatibleUnreachableCalls(BasicBlock *BB, continue; bool CanMerge = true; - for (unsigned i = 0; i < CI->arg_size(); ++i) { - if (CI->getArgOperand(i) != OtherCI->getArgOperand(i) && - !canReplaceOperandWithVariable(CI, i)) { + for (unsigned i = 0, e = CI->getNumOperands(); i != e; ++i) { + if (CI->getOperand(i) != OtherCI->getOperand(i)) { + if (CI->isDataOperand(&CI->getOperandUse(i)) && + canReplaceOperandWithVariable(CI, i)) + continue; CanMerge = false; break; } } + if (CanMerge) BlocksToMerge.push_back(OtherBB); } @@ -5854,11 +5857,14 @@ static bool mergeCompatibleUnreachableCalls(BasicBlock *BB, if (DTU) Updates.reserve(2 * BlocksToMerge.size()); - for (unsigned i = 0; i < MergedCall->arg_size(); ++i) { + for (unsigned i = 0, e = MergedCall->getNumOperands(); i != e; ++i) { + if (!MergedCall->isDataOperand(&MergedCall->getOperandUse(i))) + continue; + bool NeedsPHI = false; for (BasicBlock *OldBB : BlocksToMerge) { auto *OldCI = cast<CallInst>(&OldBB->front()); - if (OldCI->getArgOperand(i) != CI->getArgOperand(i)) { + if (OldCI->getOperand(i) != CI->getOperand(i)) { NeedsPHI = true; break; } @@ -5866,13 +5872,13 @@ static bool mergeCompatibleUnreachableCalls(BasicBlock *BB, if (NeedsPHI) { PHINode *PN = - PHINode::Create(CI->getArgOperand(i)->getType(), BlocksToMerge.size(), + PHINode::Create(CI->getOperand(i)->getType(), BlocksToMerge.size(), "", MergedCall->getIterator()); for (BasicBlock *OldBB : BlocksToMerge) { auto *OldCI = cast<CallInst>(&OldBB->front()); - PN->addIncoming(OldCI->getArgOperand(i), OldBB); + PN->addIncoming(OldCI->getOperand(i), OldBB); } - MergedCall->setArgOperand(i, PN); + MergedCall->setOperand(i, PN); } } diff --git a/llvm/test/Transforms/PhaseOrdering/dae-dce.ll b/llvm/test/Transforms/PhaseOrdering/dae-dce.ll index 7cdddd1e4232b..ec85117f18ac5 100644 --- a/llvm/test/Transforms/PhaseOrdering/dae-dce.ll +++ b/llvm/test/Transforms/PhaseOrdering/dae-dce.ll @@ -33,9 +33,14 @@ define internal void @dead_fn2() { } define void @test(i1 %c) { -; CHECK-LABEL: @test( -; CHECK-NEXT: tail call fastcc void @capture_and_trap() -; CHECK-NEXT: unreachable +; DEFAULT-LABEL: @test( +; DEFAULT-NEXT: unreachable.merge: +; DEFAULT-NEXT: tail call fastcc void @capture_and_trap() +; DEFAULT-NEXT: unreachable +; +; LTO-LABEL: @test( +; LTO-NEXT: tail call fastcc void @capture_and_trap() +; LTO-NEXT: unreachable ; br i1 %c, label %if, label %else @@ -47,6 +52,3 @@ else: call void @capture_and_trap(ptr @dead_fn2) unreachable } -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; DEFAULT: {{.*}} -; LTO: {{.*}} >From a46ac7828482a250fd2710ca53f3309fb2372ed7 Mon Sep 17 00:00:00 2001 From: Stephen <[email protected]> Date: Tue, 18 Aug 2026 13:25:09 -0400 Subject: [PATCH 4/4] remove redundant NOTE --- clang/test/CodeGen/ubsan-trap-merge.c | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/test/CodeGen/ubsan-trap-merge.c b/clang/test/CodeGen/ubsan-trap-merge.c index 696d74a788d13..01400286ebf71 100644 --- a/clang/test/CodeGen/ubsan-trap-merge.c +++ b/clang/test/CodeGen/ubsan-trap-merge.c @@ -1,5 +1,4 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 -// NOTE: Assertions have mostly been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 // The most important assertions are the attributes at the end of the file, which // show whether -ubsan-unique-traps and -fno-sanitize-merge attach 'nomerge' // to each ubsan call. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
