llvm-project/clang/test/CodeGen/ubsan-trap-merge.c
Florian Mayer 30f2e92c69
[clang] [sanitizer] predict trap checks succeed (#134310)
Trap checks fail at most once (when the program crashes).
2025-04-04 10:58:08 -07:00

745 lines
57 KiB
C

// 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.
//
// N.B. although the clang driver defaults to -fsanitize-merge=undefined,
// clang_cc1 defaults to non-merge. (This is similar to -fsanitize-recover, for
// which the default is also applied at the driver level only.)
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 %s -o - -fsanitize-trap=signed-integer-overflow | FileCheck %s --check-prefixes=TRAP-NOMERGE
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 %s -o - | FileCheck %s --check-prefixes=HANDLER-NOMERGE
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 %s -o - -fsanitize-minimal-runtime | FileCheck %s --check-prefixes=MINRT-NOMERGE
//
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 -fno-sanitize-merge=signed-integer-overflow %s -o - -fsanitize-trap=signed-integer-overflow | FileCheck %s --check-prefixes=TRAP-NOMERGE
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 -fno-sanitize-merge=signed-integer-overflow %s -o - | FileCheck %s --check-prefixes=HANDLER-NOMERGE
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 -fno-sanitize-merge=signed-integer-overflow %s -o - -fsanitize-minimal-runtime | FileCheck %s --check-prefixes=MINRT-NOMERGE
//
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 -fsanitize-merge=signed-integer-overflow %s -o - -fsanitize-trap=signed-integer-overflow | FileCheck %s --check-prefixes=TRAP-MERGE
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 -fsanitize-merge=signed-integer-overflow %s -o - | FileCheck %s --check-prefixes=HANDLER-MERGE
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 -fsanitize-merge=signed-integer-overflow %s -o - -fsanitize-minimal-runtime | FileCheck %s --check-prefixes=MINRT-MERGE
//
// REQUIRES: x86-registered-target
// TRAP-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
// TRAP-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// TRAP-NEXT: [[ENTRY:.*:]]
// TRAP-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]]
// TRAP-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// TRAP-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]]
// TRAP: [[TRAP]]:
// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], !nosanitize [[META2]]
// TRAP-NEXT: unreachable, !nosanitize [[META2]]
// TRAP: [[CONT]]:
// TRAP-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// TRAP-NEXT: ret i32 [[TMP2]]
//
// HANDLER-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
// HANDLER-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// HANDLER-NEXT: [[ENTRY:.*:]]
// HANDLER-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]]
// HANDLER-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// HANDLER-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]]
// HANDLER: [[HANDLER_ADD_OVERFLOW]]:
// HANDLER-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]]
// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP2]], i64 125) #[[ATTR4:[0-9]+]], !nosanitize [[META2]]
// HANDLER-NEXT: unreachable, !nosanitize [[META2]]
// HANDLER: [[CONT]]:
// HANDLER-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// HANDLER-NEXT: ret i32 [[TMP3]]
//
// MINRT-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
// MINRT-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// MINRT-NEXT: [[ENTRY:.*:]]
// MINRT-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]]
// MINRT-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// MINRT-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]]
// MINRT: [[HANDLER_ADD_OVERFLOW]]:
// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4:[0-9]+]], !nosanitize [[META2]]
// MINRT-NEXT: unreachable, !nosanitize [[META2]]
// MINRT: [[CONT]]:
// MINRT-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// MINRT-NEXT: ret i32 [[TMP2]]
// 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: [[TRAP]]:
// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], !nosanitize [[META2]]
// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]]
// TRAP-NOMERGE: [[CONT]]:
// TRAP-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// 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: [[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: [[CONT]]:
// HANDLER-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// 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: [[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: [[CONT]]:
// MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// 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: [[TRAP]]:
// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], !nosanitize [[META2]]
// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META2]]
// TRAP-MERGE: [[CONT]]:
// TRAP-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// 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: [[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: [[CONT]]:
// HANDLER-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// 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: [[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: [[CONT]]:
// MINRT-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// MINRT-MERGE-NEXT: ret i32 [[TMP2]]
//
int f(int x) {
return x + 125;
}
// TRAP-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
// TRAP-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
// TRAP-NEXT: [[ENTRY:.*:]]
// TRAP-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]]
// TRAP-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// TRAP-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]]
// TRAP: [[TRAP]]:
// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NEXT: unreachable, !nosanitize [[META2]]
// TRAP: [[CONT]]:
// TRAP-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// TRAP-NEXT: ret i32 [[TMP2]]
//
// HANDLER-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
// HANDLER-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
// HANDLER-NEXT: [[ENTRY:.*:]]
// HANDLER-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]]
// HANDLER-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// HANDLER-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// HANDLER: [[HANDLER_ADD_OVERFLOW]]:
// HANDLER-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]]
// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META2]]
// HANDLER-NEXT: unreachable, !nosanitize [[META2]]
// HANDLER: [[CONT]]:
// HANDLER-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// HANDLER-NEXT: ret i32 [[TMP3]]
//
// MINRT-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
// MINRT-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
// MINRT-NEXT: [[ENTRY:.*:]]
// MINRT-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]]
// MINRT-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// MINRT-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// MINRT: [[HANDLER_ADD_OVERFLOW]]:
// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]]
// MINRT-NEXT: unreachable, !nosanitize [[META2]]
// MINRT: [[CONT]]:
// MINRT-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// MINRT-NEXT: ret i32 [[TMP2]]
// 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: [[TRAP]]:
// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]]
// TRAP-NOMERGE: [[CONT]]:
// TRAP-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// 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: [[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: [[CONT]]:
// HANDLER-NOMERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// 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: [[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: [[CONT]]:
// MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// 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: [[TRAP]]:
// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META2]]
// TRAP-MERGE: [[CONT]]:
// TRAP-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// 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: [[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: [[CONT]]:
// HANDLER-MERGE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// 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: [[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: [[CONT]]:
// MINRT-MERGE-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// MINRT-MERGE-NEXT: ret i32 [[TMP2]]
//
int g(int x) {
return x + 127;
}
//
// HANDLER-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h(
// HANDLER-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
// HANDLER-NEXT: [[ENTRY:.*:]]
// HANDLER-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]]
// HANDLER-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// HANDLER-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// HANDLER: [[HANDLER_ADD_OVERFLOW]]:
// HANDLER-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]]
// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META2]]
// HANDLER-NEXT: unreachable, !nosanitize [[META2]]
// HANDLER: [[CONT]]:
// HANDLER-NEXT: [[TMP3:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]]
// HANDLER-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1, !nosanitize [[META2]]
// HANDLER-NEXT: br i1 [[TMP4]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// HANDLER: [[HANDLER_ADD_OVERFLOW1]]:
// HANDLER-NEXT: [[TMP5:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META2]]
// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP5]], i64 129) #[[ATTR4]], !nosanitize [[META2]]
// HANDLER-NEXT: unreachable, !nosanitize [[META2]]
// HANDLER: [[CONT2]]:
// HANDLER-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP3]], 0, !nosanitize [[META2]]
// HANDLER-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// HANDLER-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP7]], i32 [[TMP6]])
// HANDLER-NEXT: ret i32 [[COND]]
//
// MINRT-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h(
// MINRT-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
// MINRT-NEXT: [[ENTRY:.*:]]
// MINRT-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]]
// MINRT-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// MINRT-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// MINRT: [[HANDLER_ADD_OVERFLOW]]:
// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]]
// MINRT-NEXT: unreachable, !nosanitize [[META2]]
// MINRT: [[CONT]]:
// MINRT-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]]
// MINRT-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]]
// MINRT-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// MINRT: [[HANDLER_ADD_OVERFLOW1]]:
// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]]
// MINRT-NEXT: unreachable, !nosanitize [[META2]]
// MINRT: [[CONT2]]:
// MINRT-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]]
// MINRT-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// MINRT-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP5]], i32 [[TMP4]])
// MINRT-NEXT: ret i32 [[COND]]
// 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: [[TRAP]]:
// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]]
// 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: [[TRAP1]]:
// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]]
// 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: [[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: [[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: [[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: [[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: [[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: [[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: [[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: [[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: [[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: [[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: [[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: [[TRAP]]:
// TRAP-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-MERGE-NEXT: unreachable, !nosanitize [[META2]]
// 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: [[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: [[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: [[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: [[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: [[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: [[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: [[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: [[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: [[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: [[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: [[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: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP5]], i32 [[TMP4]])
// MINRT-MERGE-NEXT: ret i32 [[COND]]
//
int h(int x, int y) {
x += 127;
y += 129;
return x < y ? x : y;
}
// TRAP-LABEL: define dso_local noundef i32 @m(
// TRAP-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
// TRAP-NEXT: [[ENTRY:.*:]]
// TRAP-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]]
// TRAP-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// TRAP-NEXT: br i1 [[TMP1]], label %[[TRAP_I:.*]], label %[[F_EXIT:.*]], !nosanitize [[META2]]
// TRAP: [[TRAP_I]]:
// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NEXT: unreachable, !nosanitize [[META2]]
// TRAP: [[F_EXIT]]:
// TRAP-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]]
// TRAP-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]]
// TRAP-NEXT: br i1 [[TMP3]], label %[[TRAP_I2:.*]], label %[[G_EXIT:.*]], !nosanitize [[META2]]
// TRAP: [[TRAP_I2]]:
// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NEXT: unreachable, !nosanitize [[META2]]
// TRAP: [[G_EXIT]]:
// TRAP-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// TRAP-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]]
// TRAP-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META2]]
// TRAP-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META2]]
// TRAP-NEXT: br i1 [[TMP7]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]]
// TRAP: [[TRAP]]:
// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NEXT: unreachable, !nosanitize [[META2]]
// TRAP: [[CONT]]:
// TRAP-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]]
// TRAP-NEXT: ret i32 [[TMP8]]
//
// HANDLER-LABEL: define dso_local noundef i32 @m(
// HANDLER-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
// HANDLER-NEXT: [[ENTRY:.*:]]
// HANDLER-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]]
// HANDLER-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// HANDLER-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// HANDLER: [[HANDLER_ADD_OVERFLOW_I]]:
// HANDLER-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]]
// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1]], i64 [[TMP2]], i64 125) #[[ATTR4]], !nosanitize [[META2]]
// HANDLER-NEXT: unreachable, !nosanitize [[META2]]
// HANDLER: [[F_EXIT]]:
// HANDLER-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// HANDLER-NEXT: [[TMP4:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]]
// HANDLER-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1, !nosanitize [[META2]]
// HANDLER-NEXT: br i1 [[TMP5]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// HANDLER: [[HANDLER_ADD_OVERFLOW_I2]]:
// HANDLER-NEXT: [[TMP6:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META2]]
// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2]], i64 [[TMP6]], i64 127) #[[ATTR4]], !nosanitize [[META2]]
// HANDLER-NEXT: unreachable, !nosanitize [[META2]]
// HANDLER: [[G_EXIT]]:
// HANDLER-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0, !nosanitize [[META2]]
// HANDLER-NEXT: [[TMP8:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP3]], i32 [[TMP7]]), !nosanitize [[META2]]
// HANDLER-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1, !nosanitize [[META2]]
// HANDLER-NEXT: br i1 [[TMP9]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// HANDLER: [[HANDLER_ADD_OVERFLOW]]:
// HANDLER-NEXT: [[TMP10:%.*]] = zext i32 [[TMP3]] to i64, !nosanitize [[META2]]
// HANDLER-NEXT: [[TMP11:%.*]] = zext i32 [[TMP7]] to i64, !nosanitize [[META2]]
// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR4]], !nosanitize [[META2]]
// HANDLER-NEXT: unreachable, !nosanitize [[META2]]
// HANDLER: [[CONT]]:
// HANDLER-NEXT: [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0, !nosanitize [[META2]]
// HANDLER-NEXT: ret i32 [[TMP12]]
//
// MINRT-LABEL: define dso_local noundef i32 @m(
// MINRT-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
// MINRT-NEXT: [[ENTRY:.*:]]
// MINRT-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]]
// MINRT-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// MINRT-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// MINRT: [[HANDLER_ADD_OVERFLOW_I]]:
// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]]
// MINRT-NEXT: unreachable, !nosanitize [[META2]]
// MINRT: [[F_EXIT]]:
// MINRT-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]]
// MINRT-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]]
// MINRT-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// MINRT: [[HANDLER_ADD_OVERFLOW_I2]]:
// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]]
// MINRT-NEXT: unreachable, !nosanitize [[META2]]
// MINRT: [[G_EXIT]]:
// MINRT-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
// MINRT-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]]
// MINRT-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META2]]
// MINRT-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META2]]
// MINRT-NEXT: br i1 [[TMP7]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
// MINRT: [[HANDLER_ADD_OVERFLOW]]:
// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]]
// MINRT-NEXT: unreachable, !nosanitize [[META2]]
// MINRT: [[CONT]]:
// MINRT-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]]
// MINRT-NEXT: ret i32 [[TMP8]]
// 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: [[TRAP_I]]:
// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]]
// 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: [[TRAP_I2]]:
// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]]
// 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: [[TRAP]]:
// TRAP-NOMERGE-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NOMERGE-NEXT: unreachable, !nosanitize [[META2]]
// TRAP-NOMERGE: [[CONT]]:
// TRAP-NOMERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]]
// 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: [[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: [[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: [[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: [[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: [[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: [[CONT]]:
// HANDLER-NOMERGE-NEXT: [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0, !nosanitize [[META2]]
// 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: [[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: [[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: [[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: [[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: [[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: [[CONT]]:
// MINRT-NOMERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]]
// 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: [[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: [[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: [[CONT]]:
// TRAP-MERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]]
// TRAP-MERGE-NEXT: ret i32 [[TMP8]]
//
// 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: [[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: [[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: [[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: [[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: [[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: [[CONT]]:
// HANDLER-MERGE-NEXT: [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0, !nosanitize [[META2]]
// 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: [[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: [[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: [[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: [[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: [[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: [[CONT]]:
// MINRT-MERGE-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]]
// 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}