From 6e9057b0ef152f7a0ef7b2c523f7b10f20ba9197 Mon Sep 17 00:00:00 2001
From: Chris Lattner
+ %A = fdiv undef, %X + %B = fdiv %X, undef +Safe: + %A = undef +b: unreachable ++
These examples show the crucial difference between an undefined +value and undefined behavior. An undefined value (like undef) is +allowed to have an arbitrary bit-pattern. This means that the %A operation +can be constant folded to undef because the undef could be an SNaN, and fdiv is +not (currently) defined on SNaN's. However, in the second example, we can make +a more aggressive assumption: because the undef is allowed to be an arbitrary +value, we are allowed to assume that it could be zero. Since a divide by zero +is has undefined behavior, we are allowed to assume that the operation +does not execute at all. This allows us to delete the divide and all code after +it: since the undefined operation "can't happen", the optimizer can assume that +it occurs in dead code. +
+ ++a: store undef -> %X +b: store %X -> undef +Safe: +a: <deleted> +b: unreachable ++
These examples reiterate the fdiv example: a store "of" an undefined value +can be assumed to not have any effect: we can assume that the value is +overwritten with bits that happen to match what was already there. However, a +store "to" an undefined location could clobber arbitrary memory, therefore, it +has undefined behavior.
+