ok this one is a bit of a pain so please bear with me:
declare i7 @llvm.fshl.i7(i7, i7, i7) #0
define i7 @f(i7 %0, i7 %1, i6 %2) {
%4 = sext i6 %2 to i7
%5 = call i7 @llvm.fshl.i7(i7 %0, i7 %1, i7 %4)
ret i7 %5
}
let's play through what this code should do when called as f(8, 0, 39)
%0 = 0b0001000
%1 = 0b0000000
%2 = 0b100111
%4 = 0b1100111
the concatenation of %0 and %1 is 0b00010000000000 and the shift amount is 103 mod 7, or 5. thus, after the shift we get a run of all zeroes, therefore f(8, 0, 39) should be 0.
Alive2 agrees with this analysis: https://alive2.llvm.org/ce/z/Ph-9vE
but this isn't what we get from either the x64 or arm64 backend. let's use this driver:
#include <stdio.h>
// define i7 @f(i7 %0, i7 %1, i6 %2) {
unsigned f(unsigned, unsigned, unsigned);
int main(void) {
printf("%u\n", f(8, 0, 39));
return 0;
}
on x64 we get:
regehr@john-home:~$ llc foo.ll && clang foo.c foo.s && ./a.out
8
regehr@john-home:~$
and on arm64:
Johns-MacBook-Pro:~ regehr$ ~/llvm-project/for-alive/bin/llc foo.ll && clang foo.c foo.s && ./a.out
8
Johns-MacBook-Pro:~ regehr$
cc @ornata @nunoplopes @ryan-berger @nbushehri @zhengyang92 @aqjune @Hatsunespica
ok this one is a bit of a pain so please bear with me:
let's play through what this code should do when called as
f(8, 0, 39)%0 = 0b0001000%1 = 0b0000000%2 = 0b100111%4 = 0b1100111the concatenation of
%0and%1is0b00010000000000and the shift amount is 103 mod 7, or 5. thus, after the shift we get a run of all zeroes, thereforef(8, 0, 39)should be0.Alive2 agrees with this analysis: https://alive2.llvm.org/ce/z/Ph-9vE
but this isn't what we get from either the x64 or arm64 backend. let's use this driver:
on x64 we get:
and on arm64:
cc @ornata @nunoplopes @ryan-berger @nbushehri @zhengyang92 @aqjune @Hatsunespica