[llvm] [NFC][clang] Add ubsan-trap-merge.ll test to show absence of nomerge considered harmful (PR #117657)

Thurston Dang via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 26 10:17:50 PST 2024


https://github.com/thurstond updated https://github.com/llvm/llvm-project/pull/117657

>From bb737b0a70da79b917db2754e57b5387a242becc Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 26 Nov 2024 01:12:05 +0000
Subject: [PATCH 1/4] [NFC][clang] Add ubsan-trap-merge.ll test to show absence
 of nomerge considered harmful

This testcase demonstrates that when nomerge is missing from ubsantrap
intrinsics, they may be merged when inlining.

This is based on the observation and testcase by Vitaly Buka in https://github.com/llvm/llvm-project/pull/83470
---
 llvm/test/MC/X86/ubsan-trap-merge.ll | 181 +++++++++++++++++++++++++++
 1 file changed, 181 insertions(+)
 create mode 100644 llvm/test/MC/X86/ubsan-trap-merge.ll

diff --git a/llvm/test/MC/X86/ubsan-trap-merge.ll b/llvm/test/MC/X86/ubsan-trap-merge.ll
new file mode 100644
index 00000000000000..b96c85473e5387
--- /dev/null
+++ b/llvm/test/MC/X86/ubsan-trap-merge.ll
@@ -0,0 +1,181 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -O3 -mtriple x86_64 -filetype asm -o - %s | FileCheck %s
+;
+; 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.
+;
+; ModuleID = '../clang/test/CodeGen/ubsan-trap-merge.c'
+source_filename = "../clang/test/CodeGen/ubsan-trap-merge.c"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define dso_local range(i32 -2147483523, -2147483648) i32 @f(i32 noundef %x) local_unnamed_addr #0 {
+; CHECK-LABEL: f:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addl $125, %edi
+; CHECK-NEXT:    jo .LBB0_1
+; CHECK-NEXT:  # %bb.2: # %cont
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .LBB0_1: # %trap
+; CHECK-NEXT:    ud1l 2(%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
+  unreachable, !nosanitize !5
+
+cont:                                             ; preds = %entry
+  %2 = extractvalue { i32, i1 } %0, 0, !nosanitize !5
+  ret i32 %2
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) #1
+
+; Function Attrs: cold noreturn nounwind
+declare void @llvm.ubsantrap(i8 immarg) #2
+
+; Function Attrs: nounwind uwtable
+define dso_local range(i32 -2147483521, -2147483648) i32 @g(i32 noundef %x) local_unnamed_addr #0 {
+; CHECK-LABEL: g:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addl $127, %edi
+; CHECK-NEXT:    jo .LBB1_1
+; CHECK-NEXT:  # %bb.2: # %cont
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .LBB1_1: # %trap
+; CHECK-NEXT:    ud1l 2(%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
+  unreachable, !nosanitize !5
+
+cont:                                             ; preds = %entry
+  %2 = extractvalue { i32, i1 } %0, 0, !nosanitize !5
+  ret i32 %2
+}
+
+; Function Attrs: nounwind uwtable
+define dso_local range(i32 -2147483521, -2147483648) i32 @h(i32 noundef %x, i32 noundef %y) local_unnamed_addr #0 {
+; CHECK-LABEL: h:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addl $127, %edi
+; CHECK-NEXT:    jo .LBB2_3
+; CHECK-NEXT:  # %bb.1: # %cont
+; CHECK-NEXT:    addl $129, %esi
+; CHECK-NEXT:    jo .LBB2_4
+; 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
+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
+  unreachable, !nosanitize !5
+
+cont:                                             ; preds = %entry
+  %2 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 129), !nosanitize !5
+  %3 = extractvalue { i32, i1 } %2, 1, !nosanitize !5
+  br i1 %3, label %trap1, label %cont2, !nosanitize !5
+
+trap1:                                            ; preds = %cont
+  tail call void @llvm.ubsantrap(i8 4) #4, !nosanitize !5
+  unreachable, !nosanitize !5
+
+cont2:                                            ; preds = %cont
+  %4 = extractvalue { i32, i1 } %2, 0, !nosanitize !5
+  %5 = extractvalue { i32, i1 } %0, 0, !nosanitize !5
+  %cond = tail call i32 @llvm.smin.i32(i32 %5, i32 %4)
+  ret i32 %cond
+}
+
+; Function Attrs: nounwind uwtable
+define dso_local noundef i32 @m(i32 noundef %x, i32 noundef %y) local_unnamed_addr #0 {
+; CHECK-LABEL: m:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addl $125, %edi
+; CHECK-NEXT:    jo .LBB3_4
+; CHECK-NEXT:  # %bb.1: # %f.exit
+; CHECK-NEXT:    addl $127, %esi
+; CHECK-NEXT:    jo .LBB3_4
+; CHECK-NEXT:  # %bb.2: # %g.exit
+; CHECK-NEXT:    addl %esi, %edi
+; CHECK-NEXT:    jo .LBB3_4
+; CHECK-NEXT:  # %bb.3: # %cont
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .LBB3_4: # %trap.i
+; CHECK-NEXT:    ud1l 2(%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
+  unreachable, !nosanitize !5
+
+f.exit:                                           ; preds = %entry
+  %2 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 127), !nosanitize !5
+  %3 = extractvalue { i32, i1 } %2, 1, !nosanitize !5
+  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
+  unreachable, !nosanitize !5
+
+g.exit:                                           ; preds = %f.exit
+  %4 = extractvalue { i32, i1 } %0, 0, !nosanitize !5
+  %5 = extractvalue { i32, i1 } %2, 0, !nosanitize !5
+  %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %4, i32 %5), !nosanitize !5
+  %7 = extractvalue { i32, i1 } %6, 1, !nosanitize !5
+  br i1 %7, label %trap, label %cont, !nosanitize !5
+
+trap:                                             ; preds = %g.exit
+  tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
+  unreachable, !nosanitize !5
+
+cont:                                             ; preds = %g.exit
+  %8 = extractvalue { i32, i1 } %6, 0, !nosanitize !5
+  ret i32 %8
+}
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare i32 @llvm.smin.i32(i32, i32) #3
+
+attributes #0 = { nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #2 = { cold noreturn nounwind }
+attributes #3 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #4 = { noreturn nounwind }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"uwtable", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git fe3c23b439b9a2d00442d9bc6a4ca86f73066a3d)"}
+!5 = !{}

>From c2eec919aef6a8ae09c8f7654a1998750563cee5 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 26 Nov 2024 02:35:37 +0000
Subject: [PATCH 2/4] Add nomerge test case

---
 llvm/test/MC/X86/ubsan-trap-nomerge.ll | 186 +++++++++++++++++++++++++
 1 file changed, 186 insertions(+)
 create mode 100644 llvm/test/MC/X86/ubsan-trap-nomerge.ll

diff --git a/llvm/test/MC/X86/ubsan-trap-nomerge.ll b/llvm/test/MC/X86/ubsan-trap-nomerge.ll
new file mode 100644
index 00000000000000..d6343a2f73084d
--- /dev/null
+++ b/llvm/test/MC/X86/ubsan-trap-nomerge.ll
@@ -0,0 +1,186 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -O3 -mtriple x86_64 -filetype asm -o - %s | FileCheck %s
+;
+; 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 with
+; 'nomerge' manually added to ubsantraps.
+;
+; ModuleID = '../clang/test/CodeGen/ubsan-trap-merge.c'
+source_filename = "../clang/test/CodeGen/ubsan-trap-merge.c"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define dso_local range(i32 -2147483523, -2147483648) i32 @f(i32 noundef %x) local_unnamed_addr #0 {
+; CHECK-LABEL: f:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addl $125, %edi
+; CHECK-NEXT:    jo .LBB0_1
+; CHECK-NEXT:  # %bb.2: # %cont
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .LBB0_1: # %trap
+; CHECK-NEXT:    ud1l 2(%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
+  unreachable, !nosanitize !5
+
+cont:                                             ; preds = %entry
+  %2 = extractvalue { i32, i1 } %0, 0, !nosanitize !5
+  ret i32 %2
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) #1
+
+; Function Attrs: cold noreturn nounwind
+declare void @llvm.ubsantrap(i8 immarg) #2
+
+; Function Attrs: nounwind uwtable
+define dso_local range(i32 -2147483521, -2147483648) i32 @g(i32 noundef %x) local_unnamed_addr #0 {
+; CHECK-LABEL: g:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addl $127, %edi
+; CHECK-NEXT:    jo .LBB1_1
+; CHECK-NEXT:  # %bb.2: # %cont
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .LBB1_1: # %trap
+; CHECK-NEXT:    ud1l 2(%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
+  unreachable, !nosanitize !5
+
+cont:                                             ; preds = %entry
+  %2 = extractvalue { i32, i1 } %0, 0, !nosanitize !5
+  ret i32 %2
+}
+
+; Function Attrs: nounwind uwtable
+define dso_local range(i32 -2147483521, -2147483648) i32 @h(i32 noundef %x, i32 noundef %y) local_unnamed_addr #0 {
+; CHECK-LABEL: h:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addl $127, %edi
+; CHECK-NEXT:    jo .LBB2_3
+; CHECK-NEXT:  # %bb.1: # %cont
+; CHECK-NEXT:    addl $129, %esi
+; CHECK-NEXT:    jo .LBB2_4
+; 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
+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
+  unreachable, !nosanitize !5
+
+cont:                                             ; preds = %entry
+  %2 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 129), !nosanitize !5
+  %3 = extractvalue { i32, i1 } %2, 1, !nosanitize !5
+  br i1 %3, label %trap1, label %cont2, !nosanitize !5
+
+trap1:                                            ; preds = %cont
+  tail call void @llvm.ubsantrap(i8 4) #4, !nosanitize !5
+  unreachable, !nosanitize !5
+
+cont2:                                            ; preds = %cont
+  %4 = extractvalue { i32, i1 } %2, 0, !nosanitize !5
+  %5 = extractvalue { i32, i1 } %0, 0, !nosanitize !5
+  %cond = tail call i32 @llvm.smin.i32(i32 %5, i32 %4)
+  ret i32 %cond
+}
+
+; Function Attrs: nounwind uwtable
+define dso_local noundef i32 @m(i32 noundef %x, i32 noundef %y) local_unnamed_addr #0 {
+; CHECK-LABEL: m:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addl $125, %edi
+; CHECK-NEXT:    jo .LBB3_4
+; CHECK-NEXT:  # %bb.1: # %f.exit
+; CHECK-NEXT:    addl $127, %esi
+; CHECK-NEXT:    jo .LBB3_5
+; CHECK-NEXT:  # %bb.2: # %g.exit
+; CHECK-NEXT:    addl %esi, %edi
+; CHECK-NEXT:    jo .LBB3_6
+; CHECK-NEXT:  # %bb.3: # %cont
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .LBB3_4: # %trap.i
+; CHECK-NEXT:    ud1l 2(%eax), %eax
+; CHECK-NEXT:  .LBB3_5: # %trap.i2
+; CHECK-NEXT:    ud1l 2(%eax), %eax
+; CHECK-NEXT:  .LBB3_6: # %trap
+; CHECK-NEXT:    ud1l 2(%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
+  unreachable, !nosanitize !5
+
+f.exit:                                           ; preds = %entry
+  %2 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 127), !nosanitize !5
+  %3 = extractvalue { i32, i1 } %2, 1, !nosanitize !5
+  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
+  unreachable, !nosanitize !5
+
+g.exit:                                           ; preds = %f.exit
+  %4 = extractvalue { i32, i1 } %0, 0, !nosanitize !5
+  %5 = extractvalue { i32, i1 } %2, 0, !nosanitize !5
+  %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %4, i32 %5), !nosanitize !5
+  %7 = extractvalue { i32, i1 } %6, 1, !nosanitize !5
+  br i1 %7, label %trap, label %cont, !nosanitize !5
+
+trap:                                             ; preds = %g.exit
+  tail call void @llvm.ubsantrap(i8 2) #4, !nosanitize !5
+  unreachable, !nosanitize !5
+
+cont:                                             ; preds = %g.exit
+  %8 = extractvalue { i32, i1 } %6, 0, !nosanitize !5
+  ret i32 %8
+}
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare i32 @llvm.smin.i32(i32, i32) #3
+
+attributes #0 = { nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #2 = { cold noreturn nounwind }
+attributes #3 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #4 = { nomerge noreturn nounwind }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"uwtable", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git fe3c23b439b9a2d00442d9bc6a4ca86f73066a3d)"}
+!5 = !{}

>From 03db448a8952983f42a28197fea53cc43a1231aa Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 26 Nov 2024 18:09:22 +0000
Subject: [PATCH 3/4] Move .ll tests to CodeGen directory

---
 llvm/test/{MC => CodeGen}/X86/ubsan-trap-merge.ll   | 0
 llvm/test/{MC => CodeGen}/X86/ubsan-trap-nomerge.ll | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename llvm/test/{MC => CodeGen}/X86/ubsan-trap-merge.ll (100%)
 rename llvm/test/{MC => CodeGen}/X86/ubsan-trap-nomerge.ll (100%)

diff --git a/llvm/test/MC/X86/ubsan-trap-merge.ll b/llvm/test/CodeGen/X86/ubsan-trap-merge.ll
similarity index 100%
rename from llvm/test/MC/X86/ubsan-trap-merge.ll
rename to llvm/test/CodeGen/X86/ubsan-trap-merge.ll
diff --git a/llvm/test/MC/X86/ubsan-trap-nomerge.ll b/llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll
similarity index 100%
rename from llvm/test/MC/X86/ubsan-trap-nomerge.ll
rename to llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll

>From 48de3e0690178506b53c04282d131abbf18af985 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 26 Nov 2024 18:17:25 +0000
Subject: [PATCH 4/4] Fix nomerge test comment

---
 llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll b/llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll
index d6343a2f73084d..683e318011b8e0 100644
--- a/llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll
+++ b/llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll
@@ -1,8 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc -O3 -mtriple x86_64 -filetype asm -o - %s | FileCheck %s
 ;
-; 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).
+; 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.



More information about the llvm-commits mailing list