Skip to content

fshl-related miscompile by arm64 and x86-64 backends #55296

@regehr

Description

@regehr

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions