Skip to content

Commit

Permalink
[ubsan] Change ubsan-unique-traps to use nomerge instead of counter (l…
Browse files Browse the repository at this point in the history
…lvm#117651)

llvm#65972 (continuation of
https://reviews.llvm.org/D148654) had considered adding nomerge to
ubsantrap, but did not proceed with that because of
llvm#53011. Instead, it added a
counter (based on TrapBB->getParent()->size()) to each ubsantrap call.
However, this counter is not guaranteed to be unique after inlining, as
shown by llvm#83470, which can
result in ubsantraps being merged by the backend.

llvm#101549 has since fixed the
nomerge limitation ("It sets nomerge flag for the node if the
instruction has nomerge arrtibute."). This patch therefore takes
advantage of nomerge instead of using the counter, guaranteeing that the
ubsantraps are not merged.

This patch is equivalent to
llvm#83470 but also adds nomerge
and updates tests (llvm#117649:
ubsan-trap-merge.c; llvm#117657:
ubsan-trap-merge.ll, ubsan-trap-nomerge.ll; catch-undef-behavior.c).
  • Loading branch information
thurstond authored Nov 27, 2024
1 parent bc1e0c5 commit 0d15d46
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 52 deletions.
19 changes: 10 additions & 9 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3905,9 +3905,11 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,

llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];

if (!ClSanitizeDebugDeoptimization &&
CGM.getCodeGenOpts().OptimizationLevel && TrapBB &&
(!CurCodeDecl || !CurCodeDecl->hasAttr<OptimizeNoneAttr>())) {
bool NoMerge = ClSanitizeDebugDeoptimization ||
!CGM.getCodeGenOpts().OptimizationLevel ||
(CurCodeDecl && CurCodeDecl->hasAttr<OptimizeNoneAttr>());

if (TrapBB && !NoMerge) {
auto Call = TrapBB->begin();
assert(isa<llvm::CallInst>(Call) && "Expected call in trap BB");

Expand All @@ -3919,18 +3921,17 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
Builder.CreateCondBr(Checked, Cont, TrapBB);
EmitBlock(TrapBB);

llvm::CallInst *TrapCall = Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
llvm::ConstantInt::get(CGM.Int8Ty,
ClSanitizeDebugDeoptimization
? TrapBB->getParent()->size()
: static_cast<uint64_t>(CheckHandlerID)));
llvm::CallInst *TrapCall =
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));

if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
CGM.getCodeGenOpts().TrapFuncName);
TrapCall->addFnAttr(A);
}
if (NoMerge)
TrapCall->addFnAttr(llvm::Attribute::NoMerge);
TrapCall->setDoesNotReturn();
TrapCall->setDoesNotThrow();
Builder.CreateUnreachable();
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGen/bounds-checking.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ char B2[10];
// CHECK-LABEL: @f8
void f8(int i, int k) {
// NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
// NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
// NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
B[i] = '\0';

// NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
// NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
// NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
B2[k] = '\0';
}

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGen/catch-undef-behavior.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,4 +470,4 @@ void call_nonnull_variadic(int a, int *b) {

// CHECK-UBSAN: ![[WEIGHT_MD]] = !{!"branch_weights", i32 1048575, i32 1}

// CHECK-TRAP: attributes [[NR_NUW]] = { noreturn nounwind }
// CHECK-TRAP: attributes [[NR_NUW]] = { nomerge noreturn nounwind }
18 changes: 9 additions & 9 deletions clang/test/CodeGen/ubsan-trap-merge.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// NOTE: Assertions have mostly been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// The most important assertion is the attributes at the end of the file, which
// shows that ubsan does not currently attach 'nomerge'.
// shows that -ubsan-unique-traps attaches 'nomerge' to each ubsantrap intrinsic.
//
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -O3 -mllvm -ubsan-unique-traps %s -o - \
// RUN: | FileCheck %s
Expand All @@ -14,7 +14,7 @@
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// CHECK-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]]
// CHECK: [[TRAP]]:
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], !nosanitize [[META2]]
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], !nosanitize [[META2]]
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
// CHECK: [[CONT]]:
// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
Expand All @@ -31,7 +31,7 @@ int f(int x) {
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// CHECK-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]]
// CHECK: [[TRAP]]:
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
// CHECK: [[CONT]]:
// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
Expand All @@ -48,14 +48,14 @@ int g(int x) {
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// CHECK-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]]
// CHECK: [[TRAP]]:
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
// CHECK: [[CONT]]:
// CHECK-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]]
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]]
// CHECK-NEXT: br i1 [[TMP3]], label %[[TRAP1:.*]], label %[[CONT2:.*]], !nosanitize [[META2]]
// CHECK: [[TRAP1]]:
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 4) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
// CHECK: [[CONT2]]:
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]]
Expand All @@ -76,14 +76,14 @@ int h(int x, int y) {
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
// CHECK-NEXT: br i1 [[TMP1]], label %[[TRAP_I:.*]], label %[[F_EXIT:.*]], !nosanitize [[META2]]
// CHECK: [[TRAP_I]]:
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
// CHECK: [[F_EXIT]]:
// CHECK-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]]
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]]
// CHECK-NEXT: br i1 [[TMP3]], label %[[TRAP_I2:.*]], label %[[G_EXIT:.*]], !nosanitize [[META2]]
// CHECK: [[TRAP_I2]]:
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
// CHECK: [[G_EXIT]]:
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
Expand All @@ -92,7 +92,7 @@ int h(int x, int y) {
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META2]]
// CHECK-NEXT: br i1 [[TMP7]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]]
// CHECK: [[TRAP]]:
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
// CHECK: [[CONT]]:
// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]]
Expand All @@ -102,4 +102,4 @@ int m(int x, int y) {
return f(x) + g(y);
}
//.
// CHECK: attributes #[[ATTR4]] = { noreturn nounwind }
// CHECK: attributes #[[ATTR4]] = { nomerge noreturn nounwind }
29 changes: 14 additions & 15 deletions llvm/test/CodeGen/X86/ubsan-trap-merge.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
; This test shows that ubsantrap can, in the absence of nomerge, be merged by
; the backend into a single ud1 instruction (thus making debugging difficult).
;
; The LLVM IR was generated from clang/test/CodeGen/ubsan-trap-merge.c.
; The LLVM IR was generated from clang/test/CodeGen/ubsan-trap-merge.c with
; 'nomerge' manually removed from ubsantraps.
;
; ModuleID = '../clang/test/CodeGen/ubsan-trap-merge.c'
source_filename = "../clang/test/CodeGen/ubsan-trap-merge.c"
Expand All @@ -21,14 +22,14 @@ define dso_local range(i32 -2147483523, -2147483648) i32 @f(i32 noundef %x) loca
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB0_1: # %trap
; CHECK-NEXT: ud1l 2(%eax), %eax
; CHECK-NEXT: ud1l (%eax), %eax
entry:
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 125), !nosanitize !5
%1 = extractvalue { i32, i1 } %0, 1, !nosanitize !5
br i1 %1, label %trap, label %cont, !nosanitize !5

trap: ; preds = %entry
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

cont: ; preds = %entry
Expand All @@ -52,14 +53,14 @@ define dso_local range(i32 -2147483521, -2147483648) i32 @g(i32 noundef %x) loca
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB1_1: # %trap
; CHECK-NEXT: ud1l 2(%eax), %eax
; CHECK-NEXT: ud1l (%eax), %eax
entry:
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 127), !nosanitize !5
%1 = extractvalue { i32, i1 } %0, 1, !nosanitize !5
br i1 %1, label %trap, label %cont, !nosanitize !5

trap: ; preds = %entry
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

cont: ; preds = %entry
Expand All @@ -75,23 +76,21 @@ define dso_local range(i32 -2147483521, -2147483648) i32 @h(i32 noundef %x, i32
; CHECK-NEXT: jo .LBB2_3
; CHECK-NEXT: # %bb.1: # %cont
; CHECK-NEXT: addl $129, %esi
; CHECK-NEXT: jo .LBB2_4
; CHECK-NEXT: jo .LBB2_3
; CHECK-NEXT: # %bb.2: # %cont2
; CHECK-NEXT: cmpl %esi, %edi
; CHECK-NEXT: cmovll %edi, %esi
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB2_3: # %trap
; CHECK-NEXT: ud1l 2(%eax), %eax
; CHECK-NEXT: .LBB2_4: # %trap1
; CHECK-NEXT: ud1l 4(%eax), %eax
; CHECK-NEXT: ud1l (%eax), %eax
entry:
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 127), !nosanitize !5
%1 = extractvalue { i32, i1 } %0, 1, !nosanitize !5
br i1 %1, label %trap, label %cont, !nosanitize !5

trap: ; preds = %entry
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

cont: ; preds = %entry
Expand All @@ -100,7 +99,7 @@ cont: ; preds = %entry
br i1 %3, label %trap1, label %cont2, !nosanitize !5

trap1: ; preds = %cont
tail call void @llvm.ubsantrap(i8 4) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

cont2: ; preds = %cont
Expand All @@ -126,14 +125,14 @@ define dso_local noundef i32 @m(i32 noundef %x, i32 noundef %y) local_unnamed_ad
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB3_4: # %trap.i
; CHECK-NEXT: ud1l 2(%eax), %eax
; CHECK-NEXT: ud1l (%eax), %eax
entry:
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 125), !nosanitize !5
%1 = extractvalue { i32, i1 } %0, 1, !nosanitize !5
br i1 %1, label %trap.i, label %f.exit, !nosanitize !5

trap.i: ; preds = %entry
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

f.exit: ; preds = %entry
Expand All @@ -142,7 +141,7 @@ f.exit: ; preds = %entry
br i1 %3, label %trap.i2, label %g.exit, !nosanitize !5

trap.i2: ; preds = %f.exit
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

g.exit: ; preds = %f.exit
Expand All @@ -153,7 +152,7 @@ g.exit: ; preds = %f.exit
br i1 %7, label %trap, label %cont, !nosanitize !5

trap: ; preds = %g.exit
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

cont: ; preds = %g.exit
Expand Down
31 changes: 15 additions & 16 deletions llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
; This tests that the nomerge attribute for ubsantrap works correctly i.e.,
; they are lowered to separate ud1 instructions.
;
; The LLVM IR was generated from clang/test/CodeGen/ubsan-trap-merge.c with
; 'nomerge' manually added to ubsantraps.
; The LLVM IR was generated from clang/test/CodeGen/ubsan-trap-merge.c.
;
; ModuleID = '../clang/test/CodeGen/ubsan-trap-merge.c'
source_filename = "../clang/test/CodeGen/ubsan-trap-merge.c"
Expand All @@ -22,14 +21,14 @@ define dso_local range(i32 -2147483523, -2147483648) i32 @f(i32 noundef %x) loca
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB0_1: # %trap
; CHECK-NEXT: ud1l 2(%eax), %eax
; CHECK-NEXT: ud1l (%eax), %eax
entry:
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 125), !nosanitize !5
%1 = extractvalue { i32, i1 } %0, 1, !nosanitize !5
br i1 %1, label %trap, label %cont, !nosanitize !5

trap: ; preds = %entry
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

cont: ; preds = %entry
Expand All @@ -53,14 +52,14 @@ define dso_local range(i32 -2147483521, -2147483648) i32 @g(i32 noundef %x) loca
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB1_1: # %trap
; CHECK-NEXT: ud1l 2(%eax), %eax
; CHECK-NEXT: ud1l (%eax), %eax
entry:
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 127), !nosanitize !5
%1 = extractvalue { i32, i1 } %0, 1, !nosanitize !5
br i1 %1, label %trap, label %cont, !nosanitize !5

trap: ; preds = %entry
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

cont: ; preds = %entry
Expand All @@ -83,16 +82,16 @@ define dso_local range(i32 -2147483521, -2147483648) i32 @h(i32 noundef %x, i32
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB2_3: # %trap
; CHECK-NEXT: ud1l 2(%eax), %eax
; CHECK-NEXT: ud1l (%eax), %eax
; CHECK-NEXT: .LBB2_4: # %trap1
; CHECK-NEXT: ud1l 4(%eax), %eax
; CHECK-NEXT: ud1l (%eax), %eax
entry:
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 127), !nosanitize !5
%1 = extractvalue { i32, i1 } %0, 1, !nosanitize !5
br i1 %1, label %trap, label %cont, !nosanitize !5

trap: ; preds = %entry
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

cont: ; preds = %entry
Expand All @@ -101,7 +100,7 @@ cont: ; preds = %entry
br i1 %3, label %trap1, label %cont2, !nosanitize !5

trap1: ; preds = %cont
tail call void @llvm.ubsantrap(i8 4) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

cont2: ; preds = %cont
Expand All @@ -127,18 +126,18 @@ define dso_local noundef i32 @m(i32 noundef %x, i32 noundef %y) local_unnamed_ad
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB3_4: # %trap.i
; CHECK-NEXT: ud1l 2(%eax), %eax
; CHECK-NEXT: ud1l (%eax), %eax
; CHECK-NEXT: .LBB3_5: # %trap.i2
; CHECK-NEXT: ud1l 2(%eax), %eax
; CHECK-NEXT: ud1l (%eax), %eax
; CHECK-NEXT: .LBB3_6: # %trap
; CHECK-NEXT: ud1l 2(%eax), %eax
; CHECK-NEXT: ud1l (%eax), %eax
entry:
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 125), !nosanitize !5
%1 = extractvalue { i32, i1 } %0, 1, !nosanitize !5
br i1 %1, label %trap.i, label %f.exit, !nosanitize !5

trap.i: ; preds = %entry
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

f.exit: ; preds = %entry
Expand All @@ -147,7 +146,7 @@ f.exit: ; preds = %entry
br i1 %3, label %trap.i2, label %g.exit, !nosanitize !5

trap.i2: ; preds = %f.exit
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

g.exit: ; preds = %f.exit
Expand All @@ -158,7 +157,7 @@ g.exit: ; preds = %f.exit
br i1 %7, label %trap, label %cont, !nosanitize !5

trap: ; preds = %g.exit
tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
tail call void @llvm.ubsantrap(i8 0) #4, !nosanitize !5
unreachable, !nosanitize !5

cont: ; preds = %g.exit
Expand Down

0 comments on commit 0d15d46

Please sign in to comment.