Today, the following doesn't optimize further: https://llvm.godbolt.org/z/s4jrdnrcq
define noundef { i16, i1 } @src(i16 noundef %num) unnamed_addr {
start:
%r = shl nuw i16 %num, 8
%_3 = icmp ult i16 %num, 256
%0 = insertvalue { i16, i1 } poison, i16 %r, 0
%1 = insertvalue { i16, i1 } %0, i1 %_3, 1
ret { i16, i1 } %1
}
But since shifting the num left by 8 didn't overflow, that means it's definitely below 256, and the icmp is always true: https://alive2.llvm.org/ce/z/qNrDgQ
define {i16, i1, i8} @src(i16 noundef %num) noundef {
start:
%r = shl nuw i16 noundef %num, 8
%_3 = icmp ult i16 noundef %num, 256
%#0 = insertvalue {i16, i1, i8} poison, i16 %r, 0
%#1 = insertvalue {i16, i1, i8} %#0, i1 %_3, 1
ret {i16, i1, i8} %#1
}
=>
define {i16, i1, i8} @tgt(i16 noundef %num) noundef {
start:
%r = shl nuw i16 noundef %num, 8
%#0 = insertvalue {i16, i1, i8} poison, i16 %r, 0
%#1 = insertvalue {i16, i1, i8} %#0, i1 1, 1
ret {i16, i1, i8} %#1
}
Transformation seems to be correct!
Inspired by rust-lang/rust#157560 where I was adding some nuw and was surprised things didn't optimize out.
Note that the noundefs are load-bearing here: nuw is just poison-generating, not UB, so without the noundef on the return then the optimization is not legal (https://alive2.llvm.org/ce/z/K6-NnE) since someone might just never look at the product.
Today, the following doesn't optimize further: https://llvm.godbolt.org/z/s4jrdnrcq
But since shifting the
numleft by 8 didn't overflow, that means it's definitely below 256, and theicmpis always true: https://alive2.llvm.org/ce/z/qNrDgQInspired by rust-lang/rust#157560 where I was adding some
nuwand was surprised things didn't optimize out.Note that the
noundefs are load-bearing here:nuwis just poison-generating, not UB, so without thenoundefon the return then the optimization is not legal (https://alive2.llvm.org/ce/z/K6-NnE) since someone might just never look at the product.