<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">