Fix __builtin_bitreverse32 on 32-bit PowerPC
authorgkoehler <gkoehler@openbsd.org>
Wed, 21 Apr 2021 00:22:16 +0000 (00:22 +0000)
committergkoehler <gkoehler@openbsd.org>
Wed, 21 Apr 2021 00:22:16 +0000 (00:22 +0000)
This is a backport from LLVM 11.  Before this fix, code using
__builtin_bitreverse32 was crashing SIGILL because clang-10 emitted a
64-bit rldicl/clrldi instruction.  The SIGILL only happened on 32-bit
cpus, not on the G5.  The code for LLVM 11 uses __builtin_bitreverse,
so clang-10 needs this fix to build clang-11.

https://github.com/llvm/llvm-project/commit/a5d161c119d5a
https://reviews.llvm.org/D77946

ok kettenis@

gnu/llvm/llvm/lib/Target/PowerPC/PPCInstrInfo.td

index d4fa008..ff3a6de 100644 (file)
@@ -5050,8 +5050,11 @@ def RotateInsertByte1 {
   dag Left = (RLWIMI RotateInsertByte3.Left, Swap4.Bits, 8, 24, 31);
 }
 
-def : Pat<(i32 (bitreverse i32:$A)),
-  (RLDICL_32 RotateInsertByte1.Left, 0, 32)>;
+// Clear the upper half of the register when in 64-bit mode
+let Predicates = [In64BitMode] in
+def : Pat<(i32 (bitreverse i32:$A)), (RLDICL_32 RotateInsertByte1.Left, 0, 32)>;
+let Predicates = [In32BitMode] in
+def : Pat<(i32 (bitreverse i32:$A)), RotateInsertByte1.Left>;
 
 // Fast 64-bit reverse bits algorithm:
 // Step 1: 1-bit swap (swap odd 1-bit and even 1-bit):