Open rockeet opened 1 year ago
define zeroext i1 @many_or(i32 noundef %val) {
entry:
%cmp = icmp ult i32 %val, 32
tail call void @llvm.assume(i1 %cmp)
%0 = icmp ult i32 %val, 14
%switch.cast = trunc i32 %val to i14
%switch.downshift = lshr i14 -6510, %switch.cast
%1 = and i14 %switch.downshift, 1
%switch.masked = icmp ne i14 %1, 0
%2 = select i1 %0, i1 %switch.masked, i1 false
ret i1 %2
}
declare void @llvm.assume(i1 noundef)
define zeroext i1 @src(i32 noundef %val) {
entry:
%cmp = icmp ult i32 %val, 32
tail call void @llvm.assume(i1 %cmp)
%0 = icmp ult i32 %val, 14
%switch.cast = trunc i32 %val to i14
%switch.downshift = lshr i14 -6510, %switch.cast
%1 = and i14 %switch.downshift, 1
%switch.masked = icmp ne i14 %1, 0
%2 = select i1 %0, i1 %switch.masked, i1 false
ret i1 %2
}
define zeroext i1 @tgt(i32 noundef %val) {
entry:
%cmp = icmp ult i32 %val, 32
tail call void @llvm.assume(i1 %cmp)
%switch.downshift = lshr i32 9874, %val
%0 = and i32 %switch.downshift, 1
%switch.masked = icmp ne i32 %0, 0
ret i1 %switch.masked
}
declare void @llvm.assume(i1 noundef)
Transformation seems to be correct!
define zeroext i1 @many_or(i32 noundef %val) { entry: %cmp = icmp ult i32 %val, 32 tail call void @llvm.assume(i1 %cmp) %0 = icmp ult i32 %val, 14 %switch.cast = trunc i32 %val to i14 %switch.downshift = lshr i14 -6510, %switch.cast %1 = and i14 %switch.downshift, 1 %switch.masked = icmp ne i14 %1, 0 %2 = select i1 %0, i1 %switch.masked, i1 false ret i1 %2 } declare void @llvm.assume(i1 noundef)
In my code example, if __builtin_assume(val < 32)
is replaced with __builtin_assume(val < 14)
, the output code is optimal.
In your solution, it should also be fixed for 64 bits: if we write __builtin_assume(val < 64);
, it should use uint64
.
produces code:
The cmp with 14 is redundant, the optimal code should be: