[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-14 Thread Artem Labazov via Phabricator via cfe-commits
artem updated this revision to Diff 550013.
artem marked 5 inline comments as done.
artem edited the summary of this revision.
artem added a comment.

Fixed review comments


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156821/new/

https://reviews.llvm.org/D156821

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/abs-overflow.c
  compiler-rt/test/ubsan/TestCases/Misc/abs.cpp

Index: compiler-rt/test/ubsan/TestCases/Misc/abs.cpp
===
--- /dev/null
+++ compiler-rt/test/ubsan/TestCases/Misc/abs.cpp
@@ -0,0 +1,30 @@
+// REQUIRES: arch=x86_64
+//
+// RUN: %clangxx -fsanitize=signed-integer-overflow -w %s -O3 -o %t
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+//
+// RUN: %clangxx -fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow -w %s -O3 -o %t.abort
+// RUN: not %run %t.abort 2>&1 | FileCheck %s --check-prefix=ABORT
+
+#include 
+#include 
+
+int main() {
+  // ABORT: abs.cpp:[[@LINE+3]]:17: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[@LINE+2]]:17: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[@LINE+2]]:7: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
+  __builtin_abs(INT_MIN);
+  abs(INT_MIN);
+
+  // RECOVER: abs.cpp:[[@LINE+2]]:18: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'long'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[@LINE+2]]:8: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'long'; cast to an unsigned type to negate this value to itself
+  __builtin_labs(LONG_MIN);
+  labs(LONG_MIN);
+
+  // RECOVER: abs.cpp:[[@LINE+2]]:19: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'long long'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[@LINE+2]]:9: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'long long'; cast to an unsigned type to negate this value to itself
+  __builtin_llabs(LLONG_MIN);
+  llabs(LLONG_MIN);
+
+  return 0;
+}
Index: clang/test/CodeGen/abs-overflow.c
===
--- /dev/null
+++ clang/test/CodeGen/abs-overflow.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -fwrapv -fsanitize=signed-integer-overflow | FileCheck %s --check-prefix=WRAPV
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -ftrapv | FileCheck %s --check-prefixes=BOTH-TRAP,TRAPV
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefixes=BOTH-TRAP,CATCH_UB
+// COM: TODO: Support -ftrapv-handler.
+
+extern int abs(int x);
+
+int absi(int x) {
+// WRAPV:   [[NEG:%.*]] = sub i32 0, [[X:%.*]]
+// WRAPV:   [[CMP:%.*]] = icmp slt i32 [[X]], 0
+// WRAPV:   [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+//
+// BOTH-TRAP:   [[NEG:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 0, i32 [[X:%.*]])
+// BOTH-TRAP:   [[NEGV:%.*]] = extractvalue { i32, i1 } [[NEG]], 0
+// BOTH-TRAP:   [[OFL:%.*]] = extractvalue { i32, i1 } [[NEG]], 1
+// BOTH-TRAP:   [[NOFL:%.*]] = xor i1 [[OFL]], true
+// BOTH-TRAP:   br i1 [[NOFL]], label %[[CONT:.*]], label %[[TRAP:[a-zA-Z_.]*]]
+// BOTH-TRAP:   [[TRAP]]:
+// TRAPV-NEXT:llvm.ubsantrap
+// CATCH_UB:  @__ubsan_handle_negate_overflow
+// BOTH-TRAP-NEXT:unreachable
+// BOTH-TRAP:   [[CONT]]:
+// BOTH-TRAP-NEXT:[[ABSCOND:%.*]] = icmp slt i32 [[X]], 0
+// BOTH-TRAP-NEXT:select i1 [[ABSCOND]], i32 [[NEGV]], i32 [[X]]
+  return abs(x);
+}
+
+int babsi(int x) {
+// WRAPV:   [[NEG:%.*]] = sub i32 0, [[X:%.*]]
+// WRAPV:   [[CMP:%.*]] = icmp slt i32 [[X]], 0
+// WRAPV:   [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+//
+// BOTH-TRAP:   [[NEG:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 0, i32 [[X:%.*]])
+// BOTH-TRAP:   [[NEGV:%.*]] = extractvalue { i32, i1 } [[NEG]], 0
+// BOTH-TRAP:   [[OFL:%.*]] = extractvalue { i32, i1 } [[NEG]], 1
+// BOTH-TRAP:   [[NOFL:%.*]] = xor i1 [[OFL]], true
+// BOTH-TRAP:   br i1 [[NOFL]], label %[[CONT:.*]], label %[[TRAP:[a-zA-Z_.]*]]
+// BOTH-TRAP:   [[TRAP]]:
+// TRAPV-NEXT:llvm.ubsantrap
+// CATCH_UB:  @__ubsan_handle_negate_overflow
+// BOTH-TRAP-NEXT:unreachable
+// BOTH-TRAP:   [[CONT]]:
+// BOTH-TRAP-NEXT:[[ABSCOND:%.*]] = icmp slt i32 [[X]], 0
+// BOTH-TRAP-NEXT:select i1 [[ABSCOND]], i32 [[NEGV]], i32 [[X]]
+  return __builtin_abs(x);
+}
Index: clang/lib/CodeGen/CGBuiltin.cpp
==

[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-15 Thread Artem Labazov via Phabricator via cfe-commits
artem added a comment.

Thanks for the review.

I do not have commit rights, could you please push it? Artem Labazov 
<123321art...@gmail.com>


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156821/new/

https://reviews.llvm.org/D156821

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-17 Thread Artem Labazov via Phabricator via cfe-commits
artem added a comment.

Ping


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156821/new/

https://reviews.llvm.org/D156821

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-18 Thread Artem Labazov via Phabricator via cfe-commits
artem updated this revision to Diff 551656.
artem marked 2 inline comments as done.
artem added a comment.

Fixed the comments. I do not have commit rights


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156821/new/

https://reviews.llvm.org/D156821

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/abs-overflow.c
  compiler-rt/test/ubsan/TestCases/Misc/abs.cpp

Index: compiler-rt/test/ubsan/TestCases/Misc/abs.cpp
===
--- /dev/null
+++ compiler-rt/test/ubsan/TestCases/Misc/abs.cpp
@@ -0,0 +1,28 @@
+// RUN: %clangxx -fsanitize=signed-integer-overflow -w %s -O3 -o %t
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+//
+// RUN: %clangxx -fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow -w %s -O3 -o %t.abort
+// RUN: not %run %t.abort 2>&1 | FileCheck %s --check-prefix=ABORT
+
+#include 
+#include 
+
+int main() {
+  // ABORT: abs.cpp:[[@LINE+3]]:17: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[@LINE+2]]:17: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[@LINE+2]]:7: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
+  __builtin_abs(INT_MIN);
+  abs(INT_MIN);
+
+  // RECOVER: abs.cpp:[[@LINE+2]]:18: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'long'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[@LINE+2]]:8: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'long'; cast to an unsigned type to negate this value to itself
+  __builtin_labs(LONG_MIN);
+  labs(LONG_MIN);
+
+  // RECOVER: abs.cpp:[[@LINE+2]]:19: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'long long'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[@LINE+2]]:9: runtime error: negation of -{{[0-9]+}} cannot be represented in type 'long long'; cast to an unsigned type to negate this value to itself
+  __builtin_llabs(LLONG_MIN);
+  llabs(LLONG_MIN);
+
+  return 0;
+}
Index: clang/test/CodeGen/abs-overflow.c
===
--- /dev/null
+++ clang/test/CodeGen/abs-overflow.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -fwrapv -fsanitize=signed-integer-overflow | FileCheck %s --check-prefix=WRAPV
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -ftrapv | FileCheck %s --check-prefixes=BOTH-TRAP,TRAPV
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefixes=BOTH-TRAP,CATCH_UB
+// COM: TODO: Support -ftrapv-handler.
+
+extern int abs(int x);
+
+int absi(int x) {
+// WRAPV:   [[NEG:%.*]] = sub i32 0, [[X:%.*]]
+// WRAPV:   [[CMP:%.*]] = icmp slt i32 [[X]], 0
+// WRAPV:   [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+//
+// BOTH-TRAP:   [[NEG:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 0, i32 [[X:%.*]])
+// BOTH-TRAP:   [[NEGV:%.*]] = extractvalue { i32, i1 } [[NEG]], 0
+// BOTH-TRAP:   [[OFL:%.*]] = extractvalue { i32, i1 } [[NEG]], 1
+// BOTH-TRAP:   [[NOFL:%.*]] = xor i1 [[OFL]], true
+// BOTH-TRAP:   br i1 [[NOFL]], label %[[CONT:.*]], label %[[TRAP:[a-zA-Z_.]*]]
+// BOTH-TRAP:   [[TRAP]]:
+// TRAPV-NEXT:llvm.ubsantrap
+// CATCH_UB:  @__ubsan_handle_negate_overflow
+// BOTH-TRAP-NEXT:unreachable
+// BOTH-TRAP:   [[CONT]]:
+// BOTH-TRAP-NEXT:[[ABSCOND:%.*]] = icmp slt i32 [[X]], 0
+// BOTH-TRAP-NEXT:select i1 [[ABSCOND]], i32 [[NEGV]], i32 [[X]]
+  return abs(x);
+}
+
+int babsi(int x) {
+// WRAPV:   [[NEG:%.*]] = sub i32 0, [[X:%.*]]
+// WRAPV:   [[CMP:%.*]] = icmp slt i32 [[X]], 0
+// WRAPV:   [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+//
+// BOTH-TRAP:   [[NEG:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 0, i32 [[X:%.*]])
+// BOTH-TRAP:   [[NEGV:%.*]] = extractvalue { i32, i1 } [[NEG]], 0
+// BOTH-TRAP:   [[OFL:%.*]] = extractvalue { i32, i1 } [[NEG]], 1
+// BOTH-TRAP:   [[NOFL:%.*]] = xor i1 [[OFL]], true
+// BOTH-TRAP:   br i1 [[NOFL]], label %[[CONT:.*]], label %[[TRAP:[a-zA-Z_.]*]]
+// BOTH-TRAP:   [[TRAP]]:
+// TRAPV-NEXT:llvm.ubsantrap
+// CATCH_UB:  @__ubsan_handle_negate_overflow
+// BOTH-TRAP-NEXT:unreachable
+// BOTH-TRAP:   [[CONT]]:
+// BOTH-TRAP-NEXT:[[ABSCOND:%.*]] = icmp slt i32 [[X]], 0
+// BOTH-TRAP-NEXT:select i1 [[ABSCOND]], i32 [[NEGV]], i32 [[X]]
+  return __builtin_abs(x);
+}
Index: clang/lib/CodeGen/CGBuiltin.cpp
===
--- clang

[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-18 Thread Artem Labazov via Phabricator via cfe-commits
artem added inline comments.



Comment at: clang/test/ubsan/TestCases/Misc/abs.cpp:1
+// REQUIRES: arch=x86_64
+//

MaskRay wrote:
> Did you mean compiler-rt/ instead of clang/?
> 
> `// REQUIRES: arch=x86_64` is legacy style.
> 
> New style uses `// REQUIRES: target={{x86_64.*}}`
> 
> Actually, this test should be generic and we should remove REQUIRES.
I think that Aaron has moved the file when committed to the main branch. 
Anyway, moved.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156821/new/

https://reviews.llvm.org/D156821

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-21 Thread Artem Labazov via Phabricator via cfe-commits
artem updated this revision to Diff 551966.
artem marked an inline comment as done.
artem added a comment.

Rebased and fixed legacy FileCheck syntax. Gentle reminder that I do not have 
commit rights.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156821/new/

https://reviews.llvm.org/D156821

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/abs-overflow.c
  compiler-rt/test/ubsan/TestCases/Misc/abs.cpp

Index: compiler-rt/test/ubsan/TestCases/Misc/abs.cpp
===
--- /dev/null
+++ compiler-rt/test/ubsan/TestCases/Misc/abs.cpp
@@ -0,0 +1,28 @@
+// RUN: %clangxx -fsanitize=signed-integer-overflow -w %s -O3 -o %t
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+//
+// RUN: %clangxx -fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow -w %s -O3 -o %t.abort
+// RUN: not %run %t.abort 2>&1 | FileCheck %s --check-prefix=ABORT
+
+#include 
+#include 
+
+int main() {
+  // ABORT: abs.cpp:[[#@LINE+3]]:17: runtime error: negation of -[[#]] cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[#@LINE+2]]:17: runtime error: negation of -[[#]] cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[#@LINE+2]]:7: runtime error: negation of -[[#]] cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
+  __builtin_abs(INT_MIN);
+  abs(INT_MIN);
+
+  // RECOVER: abs.cpp:[[#@LINE+2]]:18: runtime error: negation of -[[#]] cannot be represented in type 'long'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[#@LINE+2]]:8: runtime error: negation of -[[#]] cannot be represented in type 'long'; cast to an unsigned type to negate this value to itself
+  __builtin_labs(LONG_MIN);
+  labs(LONG_MIN);
+
+  // RECOVER: abs.cpp:[[#@LINE+2]]:19: runtime error: negation of -[[#]] cannot be represented in type 'long long'; cast to an unsigned type to negate this value to itself
+  // RECOVER: abs.cpp:[[#@LINE+2]]:9: runtime error: negation of -[[#]] cannot be represented in type 'long long'; cast to an unsigned type to negate this value to itself
+  __builtin_llabs(LLONG_MIN);
+  llabs(LLONG_MIN);
+
+  return 0;
+}
Index: clang/test/CodeGen/abs-overflow.c
===
--- /dev/null
+++ clang/test/CodeGen/abs-overflow.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -fwrapv -fsanitize=signed-integer-overflow | FileCheck %s --check-prefix=WRAPV
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -ftrapv | FileCheck %s --check-prefixes=BOTH-TRAP,TRAPV
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefixes=BOTH-TRAP,CATCH_UB
+// COM: TODO: Support -ftrapv-handler.
+
+extern int abs(int x);
+
+int absi(int x) {
+// WRAPV:   [[NEG:%.*]] = sub i32 0, [[X:%.*]]
+// WRAPV:   [[CMP:%.*]] = icmp slt i32 [[X]], 0
+// WRAPV:   [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+//
+// BOTH-TRAP:   [[NEG:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 0, i32 [[X:%.*]])
+// BOTH-TRAP:   [[NEGV:%.*]] = extractvalue { i32, i1 } [[NEG]], 0
+// BOTH-TRAP:   [[OFL:%.*]] = extractvalue { i32, i1 } [[NEG]], 1
+// BOTH-TRAP:   [[NOFL:%.*]] = xor i1 [[OFL]], true
+// BOTH-TRAP:   br i1 [[NOFL]], label %[[CONT:.*]], label %[[TRAP:[a-zA-Z_.]*]]
+// BOTH-TRAP:   [[TRAP]]:
+// TRAPV-NEXT:llvm.ubsantrap
+// CATCH_UB:  @__ubsan_handle_negate_overflow
+// BOTH-TRAP-NEXT:unreachable
+// BOTH-TRAP:   [[CONT]]:
+// BOTH-TRAP-NEXT:[[ABSCOND:%.*]] = icmp slt i32 [[X]], 0
+// BOTH-TRAP-NEXT:select i1 [[ABSCOND]], i32 [[NEGV]], i32 [[X]]
+  return abs(x);
+}
+
+int babsi(int x) {
+// WRAPV:   [[NEG:%.*]] = sub i32 0, [[X:%.*]]
+// WRAPV:   [[CMP:%.*]] = icmp slt i32 [[X]], 0
+// WRAPV:   [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+//
+// BOTH-TRAP:   [[NEG:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 0, i32 [[X:%.*]])
+// BOTH-TRAP:   [[NEGV:%.*]] = extractvalue { i32, i1 } [[NEG]], 0
+// BOTH-TRAP:   [[OFL:%.*]] = extractvalue { i32, i1 } [[NEG]], 1
+// BOTH-TRAP:   [[NOFL:%.*]] = xor i1 [[OFL]], true
+// BOTH-TRAP:   br i1 [[NOFL]], label %[[CONT:.*]], label %[[TRAP:[a-zA-Z_.]*]]
+// BOTH-TRAP:   [[TRAP]]:
+// TRAPV-NEXT:llvm.ubsantrap
+// CATCH_UB:  @__ubsan_handle_negate_overflow
+// BOTH-TRAP-NEXT:unreachable
+// BOTH-TRAP:   [[CONT]]:
+// BOTH-TRAP-NEXT:[[ABSCOND:%.*]] = icmp slt i32 [[X]], 0
+// BOTH-TRAP-NEXT:select i1 [[ABSCOND]], i32 [[NEGV]], i32 [[X]]
+  return __builtin_abs(x);
+}
Index: clang/lib/CodeGen/CGBuiltin.cpp
===

[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-21 Thread Artem Labazov via Phabricator via cfe-commits
artem added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:1787
+if (!VCI->isMinSignedValue()) {
+  return EmitAbs(CGF, ArgValue, true);
+}

MaskRay wrote:
> MaskRay wrote:
> > nit: we delete braces in this cascading case
> > 
> > https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements
> Thanks. I think the coding standard omits the outer braces as well.
Coding standard says "Use braces on the outer `if`"



Comment at: compiler-rt/test/ubsan/TestCases/Misc/abs.cpp:11
+int main() {
+  // ABORT: abs.cpp:[[@LINE+3]]:17: runtime error: negation of -{{[0-9]+}} 
cannot be represented in type 'int'; cast to an unsigned type to negate this 
value to itself
+  // RECOVER: abs.cpp:[[@LINE+2]]:17: runtime error: negation of -{{[0-9]+}} 
cannot be represented in type 'int'; cast to an unsigned type to negate this 
value to itself

MaskRay wrote:
> FYI: `[[@LINE+3]]` is deprecated lit syntax 
> https://llvm.org/docs/CommandGuide/FileCheck.html#filecheck-pseudo-numeric-variables.
>  New code should use `[[#@LINE+3]]`
> 
> `{{[0-9]+}}` can be simplified as `[[#]]`
Thanks! Fixed


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156821/new/

https://reviews.llvm.org/D156821

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-01 Thread Artem Labazov via Phabricator via cfe-commits
artem created this revision.
artem added a reviewer: craig.topper.
Herald added subscribers: Enna1, kbarton, nemanjai.
Herald added a project: All.
artem requested review of this revision.
Herald added projects: clang, Sanitizers.
Herald added subscribers: Sanitizers, cfe-commits.

Currenly both Clang and GCC support the following set of flags that control
code gen of signed overflow:

- -fwrapv: overflow is defined as in two-complement
- -ftrapv: overflow traps
- -fsanitize=signed-integer-overflow: if undefined (no -fwrapv), then overflow 
behaviour is controlled by UBSan runtime, overrides -ftrapv

Howerver, clang ignores these flags for __builtin_abs(int) and its higher-width
versions, so passing minimum integer value always causes poison.

The same holds for *abs(), which are not handled in frontend at all but folded
to llvm.abs.* intrinsics during InstCombinePass. The intrinsics are not
instrumented by UBSan, so the functions need special handling as well.

This patch does a few things:

- Handle *abs() in CGBuiltin the same way as __builtin_*abs()
- Clang now emits llvm.abs.* intrinsic where possible
- -fsanitize=builtin,signed-integer-overflow now properly instruments abs() 
with UBSan
- -fwrapv and -ftrapv handling for abs() is made consistent with GCC

Fixes #45129 and #45794


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156821

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-macros.c
  clang/test/CodeGen/abs-overflow.c
  clang/test/CodeGen/builtin-abs.c
  clang/test/CodeGenCXX/builtins.cpp
  compiler-rt/lib/ubsan/ubsan_handlers.cpp
  compiler-rt/lib/ubsan/ubsan_handlers.h

Index: compiler-rt/lib/ubsan/ubsan_handlers.h
===
--- compiler-rt/lib/ubsan/ubsan_handlers.h
+++ compiler-rt/lib/ubsan/ubsan_handlers.h
@@ -158,6 +158,7 @@
 enum BuiltinCheckKind : unsigned char {
   BCK_CTZPassedZero,
   BCK_CLZPassedZero,
+  BCK_AbsPassedBadVal,
 };
 
 struct InvalidBuiltinData {
Index: compiler-rt/lib/ubsan/ubsan_handlers.cpp
===
--- compiler-rt/lib/ubsan/ubsan_handlers.cpp
+++ compiler-rt/lib/ubsan/ubsan_handlers.cpp
@@ -626,9 +626,13 @@
 
   ScopedReport R(Opts, Loc, ET);
 
-  Diag(Loc, DL_Error, ET,
-   "passing zero to %0, which is not a valid argument")
-<< ((Data->Kind == BCK_CTZPassedZero) ? "ctz()" : "clz()");
+  if (Data->Kind == BCK_AbsPassedBadVal) {
+Diag(Loc, DL_Error, ET,
+ "passing minimal signed integer to abs(), which results in overflow");
+  } else {
+Diag(Loc, DL_Error, ET, "passing zero to %0, which is not a valid argument")
+<< ((Data->Kind == BCK_CTZPassedZero) ? "ctz()" : "clz()");
+  }
 }
 
 void __ubsan::__ubsan_handle_invalid_builtin(InvalidBuiltinData *Data) {
Index: clang/test/CodeGenCXX/builtins.cpp
===
--- clang/test/CodeGenCXX/builtins.cpp
+++ clang/test/CodeGenCXX/builtins.cpp
@@ -53,7 +53,8 @@
 extern "C" int __builtin_abs(int); // #3
 
 int x = __builtin_abs(-2);
-// CHECK:  store i32 2, ptr @x, align 4
+// CHECK:  [[X:%.*]] = call i32 @llvm.abs.i32(i32 -2, i1 true)
+// CHECK:  store i32 [[X]], ptr @x, align 4
 
 long y = __builtin_abs(-2l);
 // CHECK:  [[Y:%.+]] = call noundef i64 @_Z13__builtin_absl(i64 noundef -2)
Index: clang/test/CodeGen/builtin-abs.c
===
--- clang/test/CodeGen/builtin-abs.c
+++ clang/test/CodeGen/builtin-abs.c
@@ -2,27 +2,21 @@
 
 int absi(int x) {
 // CHECK-LABEL: @absi(
-// CHECK:   [[NEG:%.*]] = sub nsw i32 0, [[X:%.*]]
-// CHECK:   [[CMP:%.*]] = icmp slt i32 [[X]], 0
-// CHECK:   [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+// CHECK:   [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
 //
   return __builtin_abs(x);
 }
 
 long absl(long x) {
 // CHECK-LABEL: @absl(
-// CHECK:   [[NEG:%.*]] = sub nsw i64 0, [[X:%.*]]
-// CHECK:   [[CMP:%.*]] = icmp slt i64 [[X]], 0
-// CHECK:   [[SEL:%.*]] = select i1 [[CMP]], i64 [[NEG]], i64 [[X]]
+// CHECK:   [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true)
 //
   return __builtin_labs(x);
 }
 
 long long absll(long long x) {
 // CHECK-LABEL: @absll(
-// CHECK:   [[NEG:%.*]] = sub nsw i64 0, [[X:%.*]]
-// CHECK:   [[CMP:%.*]] = icmp slt i64 [[X]], 0
-// CHECK:   [[SEL:%.*]] = select i1 [[CMP]], i64 [[NEG]], i64 [[X]]
+// CHECK:   [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true)
 //
   return __builtin_llabs(x);
 }
Index: clang/test/CodeGen/abs-overflow.c
===
--- /dev/null
+++ clang/test/CodeGen/abs-overflow.c
@@ -0,0 +1,38 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -fwrapv -fsanitize=builtin

[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-01 Thread Artem Labazov via Phabricator via cfe-commits
artem updated this revision to Diff 546261.
artem added a comment.

Fixed comments and failing test. Added a new compiler-rt test for ubsan


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156821/new/

https://reviews.llvm.org/D156821

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-macros.c
  clang/test/CodeGen/abs-overflow.c
  clang/test/CodeGen/builtin-abs.c
  clang/test/CodeGenCXX/builtins.cpp
  compiler-rt/lib/ubsan/ubsan_handlers.cpp
  compiler-rt/lib/ubsan/ubsan_handlers.h
  compiler-rt/test/ubsan/TestCases/Misc/abs.cpp

Index: compiler-rt/test/ubsan/TestCases/Misc/abs.cpp
===
--- /dev/null
+++ compiler-rt/test/ubsan/TestCases/Misc/abs.cpp
@@ -0,0 +1,26 @@
+// REQUIRES: arch=x86_64
+//
+// RUN: %clangxx -fsanitize=builtin -fno-sanitize-recover=signed-integer-overflow -w %s -O3 -o %t
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+// RUN: %clangxx -fsanitize=signed-integer-overflow -fno-sanitize-recover=builtin -w %s -O3 -o %t
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+//
+// RUN: %clangxx -fsanitize=builtin -fsanitize=signed-integer-overflow -fno-sanitize-recover=builtin -w %s -O3 -o %t.abort
+// RUN: not %run %t.abort 2>&1 | FileCheck %s --check-prefix=ABORT
+// RUN: %clangxx -fsanitize=builtin -fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow -w %s -O3 -o %t.abort
+// RUN: not %run %t.abort 2>&1 | FileCheck %s --check-prefix=ABORT
+
+#include 
+
+int main() {
+  // ABORT: abs.cpp:[[@LINE+2]]:17: runtime error: passing a minimal signed integer to abs(), which results in overflow
+  // RECOVER: abs.cpp:[[@LINE+1]]:17: runtime error: passing a minimal signed integer to abs(), which results in overflow
+  __builtin_abs(INT_MIN);
+
+  // RECOVER: abs.cpp:[[@LINE+1]]:18: runtime error: passing a minimal signed integer to abs(), which results in overflow
+  __builtin_labs(LONG_MIN);
+
+  // RECOVER: abs.cpp:[[@LINE+1]]:19: runtime error: passing a minimal signed integer to abs(), which results in overflow
+  __builtin_llabs(LLONG_MIN);
+  return 0;
+}
Index: compiler-rt/lib/ubsan/ubsan_handlers.h
===
--- compiler-rt/lib/ubsan/ubsan_handlers.h
+++ compiler-rt/lib/ubsan/ubsan_handlers.h
@@ -158,6 +158,7 @@
 enum BuiltinCheckKind : unsigned char {
   BCK_CTZPassedZero,
   BCK_CLZPassedZero,
+  BCK_AbsPassedBadVal,
 };
 
 struct InvalidBuiltinData {
Index: compiler-rt/lib/ubsan/ubsan_handlers.cpp
===
--- compiler-rt/lib/ubsan/ubsan_handlers.cpp
+++ compiler-rt/lib/ubsan/ubsan_handlers.cpp
@@ -626,9 +626,13 @@
 
   ScopedReport R(Opts, Loc, ET);
 
-  Diag(Loc, DL_Error, ET,
-   "passing zero to %0, which is not a valid argument")
-<< ((Data->Kind == BCK_CTZPassedZero) ? "ctz()" : "clz()");
+  if (Data->Kind == BCK_AbsPassedBadVal) {
+Diag(Loc, DL_Error, ET,
+ "passing minimal signed integer to abs(), which results in overflow");
+  } else {
+Diag(Loc, DL_Error, ET, "passing zero to %0, which is not a valid argument")
+<< ((Data->Kind == BCK_CTZPassedZero) ? "ctz()" : "clz()");
+  }
 }
 
 void __ubsan::__ubsan_handle_invalid_builtin(InvalidBuiltinData *Data) {
Index: clang/test/CodeGenCXX/builtins.cpp
===
--- clang/test/CodeGenCXX/builtins.cpp
+++ clang/test/CodeGenCXX/builtins.cpp
@@ -53,7 +53,8 @@
 extern "C" int __builtin_abs(int); // #3
 
 int x = __builtin_abs(-2);
-// CHECK:  store i32 2, ptr @x, align 4
+// CHECK:  [[X:%.*]] = call i32 @llvm.abs.i32(i32 -2, i1 true)
+// CHECK:  store i32 [[X]], ptr @x, align 4
 
 long y = __builtin_abs(-2l);
 // CHECK:  [[Y:%.+]] = call noundef i64 @_Z13__builtin_absl(i64 noundef -2)
Index: clang/test/CodeGen/builtin-abs.c
===
--- clang/test/CodeGen/builtin-abs.c
+++ clang/test/CodeGen/builtin-abs.c
@@ -2,27 +2,21 @@
 
 int absi(int x) {
 // CHECK-LABEL: @absi(
-// CHECK:   [[NEG:%.*]] = sub nsw i32 0, [[X:%.*]]
-// CHECK:   [[CMP:%.*]] = icmp slt i32 [[X]], 0
-// CHECK:   [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+// CHECK:   [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
 //
   return __builtin_abs(x);
 }
 
 long absl(long x) {
 // CHECK-LABEL: @absl(
-// CHECK:   [[NEG:%.*]] = sub nsw i64 0, [[X:%.*]]
-// CHECK:   [[CMP:%.*]] = icmp slt i64 [[X]], 0
-// CHECK:   [[SEL:%.*]] = select i1 [[CMP]], i64 [[NEG]], i64 [[X]]
+// CHECK:   [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true)
 //
   return __builtin_labs(x);
 }
 
 long long absll(long long x) {
 // CHECK-LABEL: @absll(
-// CHECK:   [[NEG:%.*]] = sub nsw i64 0, [[X:%.*]]
-// CHECK:   [[CMP:%.*]] = icmp slt i64 [[X]], 0
-// CHECK:   [[SEL:%.*]] = select i1 [[CMP]], i64 [[NEG]], i64 [[

[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-01 Thread Artem Labazov via Phabricator via cfe-commits
artem updated this revision to Diff 546269.
artem added a comment.

typo fix


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156821/new/

https://reviews.llvm.org/D156821

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-macros.c
  clang/test/CodeGen/abs-overflow.c
  clang/test/CodeGen/builtin-abs.c
  clang/test/CodeGenCXX/builtins.cpp
  compiler-rt/lib/ubsan/ubsan_handlers.cpp
  compiler-rt/lib/ubsan/ubsan_handlers.h
  compiler-rt/test/ubsan/TestCases/Misc/abs.cpp

Index: compiler-rt/test/ubsan/TestCases/Misc/abs.cpp
===
--- /dev/null
+++ compiler-rt/test/ubsan/TestCases/Misc/abs.cpp
@@ -0,0 +1,26 @@
+// REQUIRES: arch=x86_64
+//
+// RUN: %clangxx -fsanitize=builtin -fno-sanitize-recover=signed-integer-overflow -w %s -O3 -o %t
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+// RUN: %clangxx -fsanitize=signed-integer-overflow -fno-sanitize-recover=builtin -w %s -O3 -o %t
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+//
+// RUN: %clangxx -fsanitize=builtin -fsanitize=signed-integer-overflow -fno-sanitize-recover=builtin -w %s -O3 -o %t.abort
+// RUN: not %run %t.abort 2>&1 | FileCheck %s --check-prefix=ABORT
+// RUN: %clangxx -fsanitize=builtin -fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow -w %s -O3 -o %t.abort
+// RUN: not %run %t.abort 2>&1 | FileCheck %s --check-prefix=ABORT
+
+#include 
+
+int main() {
+  // ABORT: abs.cpp:[[@LINE+2]]:17: runtime error: passing minimal signed integer to abs(), which overflows
+  // RECOVER: abs.cpp:[[@LINE+1]]:17: runtime error: passing minimal signed integer to abs(), which overflows
+  __builtin_abs(INT_MIN);
+
+  // RECOVER: abs.cpp:[[@LINE+1]]:18: runtime error: passing minimal signed integer to abs(), which overflows
+  __builtin_labs(LONG_MIN);
+
+  // RECOVER: abs.cpp:[[@LINE+1]]:19: runtime error: passing minimal signed integer to abs(), which overflows
+  __builtin_llabs(LLONG_MIN);
+  return 0;
+}
Index: compiler-rt/lib/ubsan/ubsan_handlers.h
===
--- compiler-rt/lib/ubsan/ubsan_handlers.h
+++ compiler-rt/lib/ubsan/ubsan_handlers.h
@@ -158,6 +158,7 @@
 enum BuiltinCheckKind : unsigned char {
   BCK_CTZPassedZero,
   BCK_CLZPassedZero,
+  BCK_AbsPassedBadVal,
 };
 
 struct InvalidBuiltinData {
Index: compiler-rt/lib/ubsan/ubsan_handlers.cpp
===
--- compiler-rt/lib/ubsan/ubsan_handlers.cpp
+++ compiler-rt/lib/ubsan/ubsan_handlers.cpp
@@ -626,9 +626,13 @@
 
   ScopedReport R(Opts, Loc, ET);
 
-  Diag(Loc, DL_Error, ET,
-   "passing zero to %0, which is not a valid argument")
-<< ((Data->Kind == BCK_CTZPassedZero) ? "ctz()" : "clz()");
+  if (Data->Kind == BCK_AbsPassedBadVal) {
+Diag(Loc, DL_Error, ET,
+ "passing minimal signed integer to abs(), which overflows");
+  } else {
+Diag(Loc, DL_Error, ET, "passing zero to %0, which is not a valid argument")
+<< ((Data->Kind == BCK_CTZPassedZero) ? "ctz()" : "clz()");
+  }
 }
 
 void __ubsan::__ubsan_handle_invalid_builtin(InvalidBuiltinData *Data) {
Index: clang/test/CodeGenCXX/builtins.cpp
===
--- clang/test/CodeGenCXX/builtins.cpp
+++ clang/test/CodeGenCXX/builtins.cpp
@@ -53,7 +53,8 @@
 extern "C" int __builtin_abs(int); // #3
 
 int x = __builtin_abs(-2);
-// CHECK:  store i32 2, ptr @x, align 4
+// CHECK:  [[X:%.*]] = call i32 @llvm.abs.i32(i32 -2, i1 true)
+// CHECK:  store i32 [[X]], ptr @x, align 4
 
 long y = __builtin_abs(-2l);
 // CHECK:  [[Y:%.+]] = call noundef i64 @_Z13__builtin_absl(i64 noundef -2)
Index: clang/test/CodeGen/builtin-abs.c
===
--- clang/test/CodeGen/builtin-abs.c
+++ clang/test/CodeGen/builtin-abs.c
@@ -2,27 +2,21 @@
 
 int absi(int x) {
 // CHECK-LABEL: @absi(
-// CHECK:   [[NEG:%.*]] = sub nsw i32 0, [[X:%.*]]
-// CHECK:   [[CMP:%.*]] = icmp slt i32 [[X]], 0
-// CHECK:   [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+// CHECK:   [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
 //
   return __builtin_abs(x);
 }
 
 long absl(long x) {
 // CHECK-LABEL: @absl(
-// CHECK:   [[NEG:%.*]] = sub nsw i64 0, [[X:%.*]]
-// CHECK:   [[CMP:%.*]] = icmp slt i64 [[X]], 0
-// CHECK:   [[SEL:%.*]] = select i1 [[CMP]], i64 [[NEG]], i64 [[X]]
+// CHECK:   [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true)
 //
   return __builtin_labs(x);
 }
 
 long long absll(long long x) {
 // CHECK-LABEL: @absll(
-// CHECK:   [[NEG:%.*]] = sub nsw i64 0, [[X:%.*]]
-// CHECK:   [[CMP:%.*]] = icmp slt i64 [[X]], 0
-// CHECK:   [[SEL:%.*]] = select i1 [[CMP]], i64 [[NEG]], i64 [[X]]
+// CHECK:   [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true)
 //
   return __builtin_llabs(x);
 }
Index:

[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-07 Thread Artem Labazov via Phabricator via cfe-commits
artem added a comment.

Ping


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156821/new/

https://reviews.llvm.org/D156821

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156821: [CodeGen] [ubsan] Respect integer overflow handling in abs builtin

2023-08-10 Thread Artem Labazov via Phabricator via cfe-commits
artem added a comment.

Thanks for the feedback! I will resolve the problems in the next revision after 
some clarifications.




Comment at: clang/lib/CodeGen/CGBuiltin.cpp:2697
+bool SanitizeBuiltin = SanOpts.has(SanitizerKind::Builtin);
+bool SanitizeOverflow = SanOpts.has(SanitizerKind::SignedIntegerOverflow);
+

efriedma wrote:
> Putting the behavior under both "builtin" and "signed-integer-overflow" feels 
> a little weird; is there any precedent for that?
The problem is, we are instrumenting a builtin function, so on the one hand it 
is reasonable to be controlled by `-fsanitize=builtin`. On the other hand, GCC 
treats abs() as an arithmetic operation, so it is being instrumented by 
`-fsanitize=signed-integer-overflow` (`abs(INT_MIN)` causes a negation 
overflow).

I have decided to enable instrumentation under any of the flags, but I am not 
sure whether it is the right choice.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:2702
+case LangOptions::SOB_Defined:
+  Result = Builder.CreateBinaryIntrinsic(
+  Intrinsic::abs, EmitScalarExpr(E->getArg(0)), Builder.getFalse(),

efriedma wrote:
> Can we land the change to directly generate calls to llvm.abs() in the 
> default case separately? This might end up impacting generated code for a 
> variety of workloads, and I'd prefer to have a more clear bisect point.
I used llvm.abs() for code simplicity, since middle-end combines the 
instructions to it anyways. I think this part can be dropped entirely because 
the intrinsic is not the best possible option either (the compiler emits 
conditional move and fails to elide extra sign checks if the argument is known 
to be non-negative).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156821/new/

https://reviews.llvm.org/D156821

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits