| Issue |
179448
|
| Summary |
Miscompile with _BitInt
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
bjope
|
The test case here show a regression on trunk for clang-23: https://godbolt.org/z/xT7zG9ed9
What we have is a test case like this on C level:
```
#include <stdio.h>
signed _BitInt(121) idbi(signed _BitInt(121) b) {
return b;
}
unsigned int test_zero_llrr(unsigned int tnr) {
{
signed _BitInt(121) x;
signed _BitInt(121) res1, res2;
x = idbi(0);
res1 = x << 35;
tnr += 0x100U + (res1 == 0 ? 0 : 1) ;
x = idbi(0);
res2 = x << 35;
tnr += 0x200U + (res2 == res1 ? 0 : 2) ;
}
{
signed _BitInt(121) x;
signed _BitInt(121) res1, res2;
x = idbi(0);
res1 = x << 23;
tnr += 0x400U + (res1 == 0 ? 0 : 4) ;
x = idbi(0);
res2 = x << 23;
tnr += 0x800U + (res2 == res1 ? 0 : 8) ;
}
{
signed _BitInt(121) x;
signed _BitInt(121) res1, res2;
x = idbi(0);
res1 = x >> 61;
tnr += 0x1000U + (res1 == 0 ? 0 : 16) ;
x = idbi(0);
res2 = x >> 61;
tnr += 0x2000U + (res2 == res1 ? 0 : 32) ;
}
{
signed _BitInt(121) x;
signed _BitInt(121) res1, res2;
x = idbi(0);
res1 = x >> 23;
tnr += 0x4000U + (res1 == 0 ? 0 : 64) ;
x = idbi(0);
res2 = x >> 23;
tnr += 0x8000U + (res2 == res1 ? 0 : 128) ;
}
return tnr;
}
int main(void)
{
unsigned int tnr = test_zero_llrr(0);
printf("0x%x\n", tnr);
return tnr % 0xff;
}
```
Expected printout is "0xff00", but after commit a52177421743 ([pull request #177578](https://github.com/llvm/llvm-project/pull/177578)) the test case started to fail like this (when using x86-64 as a target and enabling ubsan):
```
> clang -O2 -fsanitize=undefined -fno-sanitize-recover=undefined test.c -o a.out
> ./a.out
0xff0f
```
I'm not quite sure if #177578 is to blame for this, or if instruction selection just is a victim for earlier misbehavior in the front/middle end.
One thing I've noticed is that the "idbi" function result in IR such as:
```
%3 = alloca i121, align 8
...
%12 = trunc i128 %11 to i121
store i121 %12, ptr %3, align 8
%13 = load { i64, i64 }, ptr %3, align 8
ret { i64, i64 } %13
```
which looks a bit suspicious. It stores an i121 and then loads { i64, i64 }.
This example show that changing the store to an i128 store would avoid the miscompile: https://godbolt.org/z/vabnsc11r
Maybe the real problem is a bit more related to commit 9ad72df55cb74b291932 ([#91364](https://github.com/llvm/llvm-project/pull/91364)), which changed a lot around ABI lowering to no longer use the non-byte-sized types. Here we still use i121 for the temporary return value alloca.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs