[llvm-dev] IR canonicalization: select or bool math?
Sanjoy Das via llvm-dev
llvm-dev at lists.llvm.org
Wed Sep 28 22:12:43 PDT 2016
My gut tells me that Hal is right, and we should prefer zexts as long
as the select boils down to one instruction, but let me go against my
intuition and try to list two reasons why we should prefer selects:
* Folding operations into selects: it is trivial to transform
f(select X, Const0, Const1) to select X, f(Const0), f(Const1),
while doing that can be difficult for zexts.
define i32 @sel_1_or_0(i1 %a) {
%b = select i1 %a, i32 1, i32 0
%k = add i32 %b, 50
ret i32 %k
}
==>
define i32 @sel_1_or_0(i1 %a) {
%b = select i1 %a, i32 51, i32 50
ret i32 %b
}
but
define i32 @sel_1_or_0(i1 %a) {
%b = zext i1 %a to i32
%k = add i32 %b, 50
ret i32 %k
}
is not as natural to transform.
* zexts (resp. sexts) lose information when combined with nuw
(resp. nsw) operations.
That is, if we inline
define i32 @sel_1_or_0(i1 %a) {
%b = zext i1 %a to i32
ret i32 %b
}
into f and get
define i32 @f(i32 %x, i32 %y) {
%x.zext = ...
%y.zext = ...
;; There are some existing use of %x.zext and %y.zext
%a = add nuw i1 %x, %y
%b = zext i1 %a to i32
ret i32 %b
}
then we'll get (following your instructions, I've not verified that
this actually happens :) )
define i32 @f(i1 %x, i1 %y) {
%x.zext = ...
%y.zext = ...
%a = add nuw i32 %x.zext, %y.zext
ret i32 %a
}
but we've now lost information -- we no longer know that %a is 0 or
1 -- it can also be 2. This would not happen if we always
canonicalized zext i1 C to iN to select C, iN 1, iN 0
-- Sanjoy
More information about the llvm-dev
mailing list