UD2 Undefined Instruction generated by Clang/LLVM
From Wikistix
Maybe I'm just slow, but I only recently learned of the UD family of x86-64 (amd64) instructions (UD0, UD1 & UD2). These are reserved undefined instructions that generate an invalid opcode exception when executed, resulting in a SIGILL (illegal instruction signal) on Unix-like operating systems.
These can be generated by Clang/LLVM (and gcc) when compiling with flags like -fsanitize=undefined -fsanitize-trap=all
.
For example, a range check is introduced when doing casts that might result in undefined behavior:
#include <cstdint>
int64_t fubar(double d) {
return static_cast<int64_t>(d);
}
Results in the following sequence:
.LCPI0_0:
.quad -4332462841530417151 # double -9.2233720368547778E+18
.LCPI0_1:
.quad 4890909195324358656 # double 9.2233720368547758E+18
.text
.globl _Z5fubard
.p2align 4, 0x90
.type _Z5fubard,@function
_Z5fubard: # @_Z5fubard
.cfi_startproc
.long 846595819 # 0x327606eb
.long .L__unnamed_1-_Z5fubard
# %bb.0:
ucomisd .LCPI0_0(%rip), %xmm0
jbe .LBB0_2
# %bb.1:
movsd .LCPI0_1(%rip), %xmm1 # xmm1 = mem[0],zero
ucomisd %xmm0, %xmm1
jbe .LBB0_2
# %bb.3:
cvttsd2si %xmm0, %rax
retq
.LBB0_2:
ud2
The UD2 instruction is invoked if the double is outside of the bounds of a signed int64.