<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/62612>62612</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
clang, clang++ optimizes out modulo 0
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
no-bugs-please
</td>
</tr>
</table>
<pre>
# I am running Ubuntu linux under Windows Subsystem Linux on
# Windows 10, on an Intel Ivy Bridge. I have written this
# unsigned round up routine to round source up to the nearest
# multiple of multiple. The routine is designed to do a
# modulo by zero, and hence give a SIGFPE if given the pesky
# multiple of zero. This works unoptimized. But optimized,
# it appears the line "result = source - source % multiple;" has
# become "result = 0;"
% uname -a
Linux dopey 5.15.90.1-microsoft-standard-WSL2 #1 SMP Fri Jan 27 02:56:13 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
% clang -v
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
% apt list clang
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Listing...
clang/bionic-updates,now 1:6.0-41~exp5~ubuntu1 amd64 [installed]
% cat clangbug2.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
/* It seems that if uroundup is compiled optimized with clang or */
/* clang++, the last else line in uroundup */
/* "else result = source - source % multiple;" */
/* gets merged with the previous "result = source;". */
/* Hence there is no floating exception for dividing by zero. */
/* This does work properly if compiled unoptimized, or with gcc. */
typedef unsigned long long ullong_t;
static char Sccsid[] = "@(#)[marx]/sys/cc/clangbug2";
char const *program = "clangbug2";
/* unsigned round up */
ullong_t
uroundup (
register ullong_t const source,
register ullong_t const multiple)
{
register ullong_t uremainder;
register ullong_t result;
if (multiple != 0) {
uremainder = source % multiple;
if (uremainder == 0)
result = source;
else
result = source + multiple - uremainder;
}
else if (source == 0)
result = source;
else
result = source - source % multiple;
return (result);
}
int
main (
register int const argcount,
register char **const argvector)
{
printf ("uroundup (1, 0) = %llu\n", uroundup (1, 0));
fflush (stdout);
exit (0);
}
% clang -O -S clangbug2.c
% cat clangbug2.s
.text
.file "clangbug2.c"
.globl uroundup # -- Begin function uroundup
.p2align 4, 0x90
.type uroundup,@function
uroundup: # @uroundup
.cfi_startproc
# %bb.0:
movq %rdi, %rcx
testq %rsi, %rsi
je .LBB0_1
# %bb.2:
xorl %edx, %edx
movq %rcx, %rax
divq %rsi
testq %rdx, %rdx
je .LBB0_4
# %bb.3:
addq %rcx, %rsi
subq %rdx, %rsi
movq %rsi, %rcx
.LBB0_4:
movq %rcx, %rax
retq
.LBB0_1:
xorl %ecx, %ecx
movq %rcx, %rax
retq
.Lfunc_end0:
.size uroundup, .Lfunc_end0-uroundup
.cfi_endproc
...
# .LBB0_1 just assigns zero to %rax
% a.out
uroundup (1, 0) = 0
# Compiled unoptimized generates a SIGFPE as desired
% clang clangbug2.c
% a.out
Floating point exception (core dumped)
# Same for clang++
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clangbug2.c:21:3: warning: 'register' storage class specifier is deprecated and incompatible with C++17 [-Wdeprecated-register]
register ullong_t const source,
^~~~~~~~~
clangbug2.c:22:3: for crying out loud would you please stop using register
6 warnings generated.
% a.out
uroundup (1, 0) = 0
% clang++ clangbug2.c
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clangbug2.c:21:3: warning: 'register' storage class specifier is deprecated and incompatible with C++17 [-Wdeprecated-register]
register ullong_t const source,
^~~~~~~~~
clangbug2.c:22:3: for crying out loud would you please stop using register
...
6 warnings generated.
% a.out
Floating point exception (core dumped)
# gcc seems to work
% gcc -O clangbug2.c
% a.out
Floating point exception (core dumped)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWc1u4zgSfhrmUpAgU5adHHKwnbg3i-zMYDKNPgaUWJY5I5Nq_iR2H_rZF6R-LMtOtnuwOSywRhDbZPGrr4rFqqLMjBGlRLwl2ZJkd1fM2a3St1JFuStNVFfIDF7lih9uCU3hAdgOtJNSyBI-505aB5WQbg9OctTwRUiuXg08udwcjMUdPIZZJYEkdyRZeJBOaJIQuvJTTMKDtFjBw8sBllrwEmN4gC17QXjVwlqUYLfCDDCcDLw5aOUkB1f7D1ZIBKvaMaOcLtBPWQV2iyCRaTT2CLJzlRV1haA2_ecY4I8t9mjCAMdWlVXAFbABi53irlKQH-AbauWtYZLDFmWBUIoXBAZPD5_Wv92D2IQBGYjUaP46wGUeHihwEAZelf7LgJOqtmInviGPYeks9F-9wiOKsMDqGpk2QUnl6RNKNRpXWSDpXeeRqPtAaNbrJumSUApbNvRyjoXajVGSRrSVamUzcJLtECLWjDTbzlWNB8jiSRbfJPEk2olCK6M2NjKWSc40j748PVIgNJ3A079-g7UW8E8mgc4hoSRdZDOSLiYpfP5jBTShKeyvZ8-z6ejt0y-fCV0HlWNWRcVkCdFLM9J8e0FthJIwi5M4iSYuhLEncW1ZaQhd_37_eL94un-eJQmh642QrCL0poH4g-kSLUkXrfKoLqJwAqJSulZkq5FxHxxYecFaGdESe5DGsqpCfie0nyJ07YwmdJ0L2UisQ-wWTHLBmUX4tFqBaFYxK5Q8W0XXcUzouhI5oeuyKAhdt8yOtOh6_rHocRYnH6rh-m-gf4BLPsgPP2b8E1ZYWOQfsGurnmfIB35huoDYn_RpsptNRwTeEzqePVZbqISxzSEczn5Z_P7Lwy-f_HIvxBUakMo2GZ-BsSyvEFaPDyCkRb1hBcbw2SC8CruFgjlvNQgJptCitiYegj8KY4Us4zgeHPrgGCVFEbna22kIXUn1ChOSLmZxEk0n33FfZ9-bZDABtuOzKZBsKboTS7K7s-TCWttyV9K46POmkEXlOAJJV8bySuTxlqT3l6adFMbyN6eN5UINZ1uZNaELeLBgEHc-2zPrC4wLdc_VvmgValeLCvmxWLS-CxlQafAvQgPWELR11jL8rZpCwowFrExbUoQ8Knr7dQGaUBpQfq4g_TB8idbADnXZmRoqrcYXoZy5WAgbDfGPgP8jlHS7RR1aAqlgUynmwwxwX2Ad4nGjNHDxIrgfbnuC-B3QUOND7PtCD7VWNerq4Ley375B8Q_Nkm5sK4siPocN_-2hRo6bY4dUKVk2_1zl356tN3ywwlhmRQHFlml4KgojeNMMBlf5Sj9NCL0mNPVFMFvumN77w0DX5uCrZUgv_THw8qfwAbdQ0ljPttaq1GzXYb-zrvXSead3bnNvWPOtC0_POowAaCyFsah7H7SM2kigq_8k2Idl1wiQ-bJb07zOVzqNOyZ8Y9yb9rZwE54jH3TiYuON6ftEQidNJ0Zv4MjjqG54uMZn6gT3iH26uENvpS8enTMgf7rPRxtrx0ee0OWx7Y3e81SI8vndJa-EdNLQ72DPqL_H4g1nD-z4iVx1AUijdVp6eu3m0pujeSObhGyj1_vhYuQK2cUi02WhnLSXwjactnBCFr3wCxZW6bcjt9ZC2uBGQunw9Ex8zmmiLBzXrKocyVbSH1a6gouiJ0a2r82mcmYb9sly5ewlGdwLnyCuk0uTI2ed9fe_QvR0oRS_UanNKXhscW9HQxtRYUivdIja3XogLiuVV_BmJfSXpyiCJZZCwsbJIhSITroDqSmrRCm7RdPgwv1NMqZ3qD2XfjVdkWnSgZ6mvKYTTIFMk5GyDqzYiGdjmba1VseOxe9tnscJSUchvFMvXxuDMs1FuHDSTBf7UymLxn5tpUwvZUQr9Se2yh-Xy-R5MtZKz7Tula5arcj3LZ7_dM6tpdOqZCMRLo70ezoXSPdKdK_klPR0TDo9I80473UdGY21Gpd_Hakciwx9bs583vF5b6fedohG-3WIM3nX9z0O9jv-82p8pD6j5OfBFRvxDYdxDQPp6J0ARsmP4ds3-n5zWqvgT-dTX3i4ZUIjBladMB1cU2Kfkc46h9Pcl5yuSmF1oUODEiVqf7s4PvhhzQMkjXyctN5JVwNK667PrJUvAMduk9DrQmkE7na1bw5vxgyf2A5DTzrs6Yd9WRhOF_DKtBTNR6ux0UbovCB0DkLWzjuyHWjuBXN43WK4f62aofCso7kvCAM5btmLULp5eFZrLJi_NJJsGX05fu_vU0M_pAvf2SzSES1C512B89qNVZqV6A0zBkyNhdgIHOtjkoOQvpNmVvj7ZOicW8aT-ZhP1GvoiP1410iy--_t66JNtLMpbIc-eA8rZ6FSjsOrchWHg3LQPG315tXgjBfqOQXUWecT00caj_8b4ZwNY-Q8MP8fKf9rkdLnxJ8Nmb-fbsqi6J5HqHChPeL7qejXD014V_w25TfpDbvC28nsOs2u6TSlV9vbAmc0oXxKeU7Z9GZOrxPEWTafYDZN06K4Erc0oWmSJdd0Mp1PaJxf5yyf5_wGi1nOizmZJv5yUsVV9bKLlS6vhDEOb2d0NqFXFcuxMuHnE0olvkKY9J1idnelb_2a8FMKmSaVMNYcUaywFd62B291cgK7imLC3re_MiRXTle3W2tr4yupvx2vS2G3Lo8LtSN07ZHbt6jW6k8sLKHrwMff0wPffwcAAP__RNiofQ">