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?