Skip to content

Differently typed arguments for primop shift makes LLVM fail

Summary

Since commit 06982b6c the LLVM code generator fails with

Error when running Shake build system:
  at action, called at src/Rules.hs:40:19 in main:Rules
  at need, called at src/Rules.hs:62:5 in main:Rules
* Depends on: _build/stage1/lib/package.conf.d/ghc-bignum-1.0.conf
  at apply1, called at src/Development/Shake/Internal/Rules/Oracle.hs:159:32 in shake-0.19.1-c7ea64c194680cf712cabbf4a6f3458de7c54133554936ab854aaa66e6ef4da0:Development.Shake.Internal.Rules.Oracle
* Depends on: OracleQ (ContextDataKey (Context {stage = Stage1, package = Package {pkgType = Library, pkgName = "ghc-bignum", pkgPath = "libraries/ghc-bignum"}, way = v}))
  at need, called at src/Hadrian/Oracles/Cabal/Rules.hs:54:9 in main:Hadrian.Oracles.Cabal.Rules
* Depends on: _build/stage1/libraries/ghc-bignum/setup-config
  at need, called at src/Rules/Library.hs:157:18 in main:Rules.Library
* Depends on: _build/stage1/libraries/ghc-prim/build/libHSghc-prim-0.8.0.a
  at need, called at src/Rules/Library.hs:152:5 in main:Rules.Library
* Depends on: _build/stage1/libraries/ghc-prim/build/GHC/PrimopWrappers.o
  at &%>, called at src/Rules/Compile.hs:77:9 in main:Rules.Compile
* Depends on: _build/stage1/libraries/ghc-prim/build/GHC/PrimopWrappers.o _build/stage1/libraries/ghc-prim/build/GHC/PrimopWrappers.hi
  at cmd', called at src/Builder.hs:312:23 in main:Builder
  at cmd, called at src/Builder.hs:408:8 in main:Builder
* Raised the exception:
Development.Shake.cmd, system command failed
Command line: _build/stage0/bin/ghc -Wall -dynamic-too -hisuf hi -osuf o -hcsuf hc -static -hide-all-packages -no-user-package-db '-package-env -' '-package-db _build/stage1/lib/package.conf.d' '-this-unit-id ghc-prim-0.8.0' '-package-id rts-1.0' -i -i/devel/ghc/_build/stage1/libraries/ghc-prim/build -i/devel/ghc/_build/stage1/libraries/ghc-prim/build/autogen -i/devel/ghc/libraries/ghc-prim -Iincludes -I_build/stage1/lib -I_build/stage1/libraries/ghc-prim/build -I/devel/ghc/_build/stage1/lib/x86_64-linux-ghc-9.1.20210107/rts-1.0/include -I_build/stage1/lib -optc-I_build/stage1/lib -optP-include -optP_build/stage1/libraries/ghc-prim/build/autogen/cabal_macros.h -outputdir _build/stage1/libraries/ghc-prim/build -Wnoncanonical-monad-instances -optc-Wno-error=inline -optP-Wno-nonportable-include-path -c _build/stage1/libraries/ghc-prim/build/GHC/PrimopWrappers.hs -o _build/stage1/libraries/ghc-prim/build/GHC/PrimopWrappers.o -O0 -H64m -this-unit-id ghc-prim -XHaskell2010 -no-global-package-db -package-db=/devel/ghc/_build/stage1/lib/package.conf.d -ghcversion-file=/devel/ghc/_build/stage1/lib/ghcversion.h -O -Wno-deprecated-flags -Wno-trustworthy-safe -fllvm
Exit code: 1
Stderr and Stdout:
/nix/store/z70l2zywr52z0p0pngb49ap6pf5c5pwj-llvm-10.0.1/bin/opt: /run/user/1007/ghc20279_0/ghc_1.ll:20379:29: error: '%ln6fe' defined with type 'i64' but expected 'i32'
  %ln6ff = lshr i32 %ln6fd, %ln6fe
                            ^
`opt' failed in phase `LLVM Optimiser'. (Exit code: 1)

The failing part of the LLVM IR is:

define ghccc void @ghczmprim_GHCziPrimopWrappers_uncheckedShiftRLWord32zh_info$def(i64* noalias nocapture %Base_Arg, i64* noalias nocapture %Sp_Arg, i64* noalias nocapture %Hp_Arg, i64 %R1_Arg, i64 %R2_Arg, i64 %R3_Arg, i64 %R4_Arg, i64 %R5_Arg, i64 %R6_Arg, i64 %SpLim_Arg) align 8 nounwind prefix <{i64, i64, i32, i32}><{i64 8589934604, i64 0, i32 14, i32 0}>
{
n6fb:
  %lB1 = alloca i64, i32 1
  %lB0 = alloca i32, i32 1
  %lc6f7 = alloca i32, i32 1
  %R1_Var = alloca i64, i32 1
  store i64 %R1_Arg, i64* %R1_Var
  br label %c6f8
c6f8:
  store i64 %R3_Arg, i64* %lB1
  %ln6fc = trunc i64 %R2_Arg to i32
  store i32 %ln6fc, i32* %lB0
  br label %c6fa
c6fa:
  %ln6fd = load i32, i32* %lB0
  %ln6fe = load i64, i64* %lB1
  ; _B0::I32
  ; _B1::I64
  %ln6ff = lshr i32 %ln6fd, %ln6fe

I think the problematic part is primop Word32SrlOp "uncheckedShiftRLWord32#" GenPrimOp Word32# -> Int# -> Word32# in conjunction of how binary operators are implemented in LLVM. For some binary operators the type of the first and second operand must be the same. Thus one option would be to change Int# into Word32 in primop, or let the LLVM code generator cast the second operand to the type of the first operand. Any thoughts about on or the other solution?

Edited by Stefan Schulze Frielinghaus
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information