Issue 90936
Summary miscompile related to coalescing stores in AArch64 SDAG backend
Labels backend:AArch64, llvm:codegen, miscompilation, llvm:SelectionDAG
Assignees
Reporter regehr
    here's a function:
```llvm
define void @f(i16 %0, ptr %1) {
  %3 = trunc i16 %0 to i8
  %4 = trunc i16 %0 to i14
  %new0 = lshr i14 %4, 8
 store i8 %3, ptr %1, align 1
  %5 = getelementptr i8, ptr %1, i64 1
 %6 = trunc i14 %new0 to i8
  store i8 %6, ptr %5, align 1
  ret void
}
```

during codegen, the two 8-bit stores are getting merged:
```
_f:    
	strh	w0, [x1]
	ret
```

but the backend seems to miss that the trunc changed the value, it dropped those 2 high bits. 
I also have versions of this that improperly merge 16-bit stores and 32-bit stores.

we can demonstrate using this driver:
```c
#include <stdio.h>

void f(unsigned short, unsigned char *);

int main(void) {
  unsigned char mem[8];

  for (int i=0; i<8; ++i)
    mem[i] = 0xee;

  f(0xFFFF, mem);

  for (int i=0; i<8; ++i)
    printf("%x\n", mem[i]);
}
```

```
Johns-MacBook-Pro:tmp regehr$ ~/llvm-project/for-alive/bin/llc foo.ll
Johns-MacBook-Pro:tmp regehr$ clang driver.c foo.s && ./a.out 
ff
ff
ee
ee
ee
ee
ee
ee
Johns-MacBook-Pro:tmp regehr$ 
```

in contrast, global isel properly notices that those high bits were chopped off:
```
Johns-MacBook-Pro:tmp regehr$ ~/llvm-project/for-alive/bin/llc foo.ll -global-isel
Johns-MacBook-Pro:tmp regehr$ clang driver.c foo.s && ./a.out 
ff
3f
ee
ee
ee
ee
ee
ee
```

cc @hatsunespica

_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to