This is an archive of the discontinued LLVM Phabricator instance.

[UBSan][MIPS] Use unsigned value while bit shifting on MIPS
AbandonedPublic

Authored by slthakur on Apr 24 2015, 3:14 AM.

Details

Summary

On MIPS, shift operation on signed types give unpredictable results. Therefore we use unsigned value while shifting and after shifting is done we convert it back to signed value.

Diff Detail

Repository
rL LLVM

Event Timeline

slthakur updated this revision to Diff 24370.Apr 24 2015, 3:14 AM
slthakur retitled this revision from to [UBSan][MIPS] .
slthakur updated this object.
slthakur edited the test plan for this revision. (Show Details)
slthakur added reviewers: rsmith, kcc, samsonov, dsanders.
slthakur set the repository for this revision to rL LLVM.
slthakur retitled this revision from [UBSan][MIPS] to [UBSan][MIPS] Use unsigned value while bit shifting on MIPS.
slthakur added subscribers: jaydeep, mohit.bhakkad, Unknown Object (MLST).
samsonov edited edge metadata.Apr 24 2015, 11:44 AM

Please elaborate what's going on here (i.e. what is the value that we fail to sign-extend)? This code looks far too complex to me, and I'd strongly suggest to make it platform-independent.

Please elaborate what's going on here (i.e. what is the value that we fail to sign-extend)?

The value that we fail to sign extend is of SIntMax(Val). We are getting uncertain results on bit shifting of signed types. Therefore we need to use unsigned types when applying bit shifting. Since return type of getSIntValue() function is SIntMax, we can type cast the return value after bit shifting to SIntMax.

This code looks far too complex to me, and I'd strongly suggest to make it platform-independent.

I have tried to simplify the code and make it platform independent. I will update this patch with the simplified code

slthakur updated this revision to Diff 24535.Apr 28 2015, 3:17 AM
slthakur edited edge metadata.

Simplified code and made it platform-independent.

dsanders edited edge metadata.Apr 28 2015, 3:26 AM

Could you confirm the type of SIntMax and the value of ExtraBits when it gives incorrect results? 'X << N >> N' is a common idiom for sign-extension so it's surprising that it's not working for you.

The type of SIntMax is __int128. The value of ExtraBits is 64 when getType().getIntegerBitWidth() returns 64 and it is 96 when getType().getIntegerBitWidth() returns 32.

I haven't identified the guilty instruction(s) yet but it looks like a CodeGen bug with 128-bit shifts. At the moment '(x << 64) == x' and '(x << 32) == (x << 96)' neither of which should be true.

What Daniel says. Looks like you should fix the MIPS CodeGen instead. As a workaround, you can try to hack ubsan_value.h to treat __int128 as unavailable on MIPS.

slthakur abandoned this revision.Apr 29 2015, 5:04 AM

http://reviews.llvm.org/D9337 fixes 128 bit shifts for mips in compiler.