Closed
Description
See https://llvm.godbolt.org/z/Gbe8xPzd9:
define i64 @umull(i64 %x) {
%lo = and i64 %x, u0xffffffff
%hi = lshr i64 %x, 32
%mul = mul i64 %lo, %hi
ret i64 %mul
}
define i64 @umull_no_mask(i64 %x, i64 %y) {
%lo = and i64 %x, u0xffffffff
%hi = and i64 %y, u0xffffffff
%mul = mul i64 %lo, %hi
ret i64 %mul
}
define i64 @umaddl(i64 %x, i64 %a) {
%lo = and i64 %x, u0xffffffff
%hi = lshr i64 %x, 32
%mul = mul i64 %lo, %hi
%add = add i64 %a, %mul
ret i64 %add
}
define i64 @umaddl2(i64 %x, i64 %y, i64 %a) {
%lo = and i64 %x, u0xffffffff
%hi = and i64 %y, u0xffffffff
%mul = mul i64 %lo, %hi
%add = add i64 %a, %mul
ret i64 %add
}
Produces:
umull: // @umull
lsr x8, x0, #32
and x9, x0, #0xffffffff
umull x0, w9, w8
ret
.Lfunc_end0:
umull_no_mask: // @umull_no_mask
umull x0, w0, w1
ret
.Lfunc_end1:
umaddl: // @umaddl
lsr x8, x0, #32
and x9, x0, #0xffffffff
umaddl x0, w9, w8, x1
ret
.Lfunc_end2:
umaddl2: // @umaddl2
and x8, x0, #0xffffffff
and x9, x1, #0xffffffff
umaddl x0, w8, w9, x2
ret
.Lfunc_end3:
The masking is redundant in all cases. Note that it does get omitted for umull if both operands are mask, but not if only one is. And for umaddl it does not happen even if both are masked.