Opened 11 years ago

Closed 10 years ago

Last modified 4 years ago

#1052 closed bug (fixed)

NCG doesn't realise shift instructions trash shifted input?

Reported by: igloo Owned by: simonmar
Priority: high Milestone: 6.8.1
Component: Compiler (NCG) Version: 6.7
Keywords: Cc:
Operating System: Linux Architecture: x86_64 (amd64)
Type of failure: None/Unknown Test Case: arith011
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


It looks like the NCG on amd64/Linux doesn't realise that shifting instructions trash the shifted input (spotted due to arith011). With this input file:

module Main where

import Data.Bits
import GHC.Exts

main = print ((2 :: Int) `qrotate` 1)

{-# NOINLINE qrotate #-}
(I# x#) `qrotate` (I# i#) =
    (I# (word2Int# (a# `or#` b#)), W# a#, W# b#)
    x'# = int2Word# x#
    i'# = word2Int# (int2Word# i# `and#` int2Word# (wsib -# 1#))
    a# = x'# `uncheckedShiftL#` i'#
    b# = x'# `uncheckedShiftRL#` (wsib -# i'#)

    wsib = 64#

compiling with -O -fglasgow-exts -v9 if I merge the Cmm and Asm output I get:

R2 == rsi
R3 == rdi

_sTh = R3;            movq %rdi,%rax  rax=_sTh
_sTj = _sTh & 63;     andq $63,%rax   rax=_sTj
_sTl = _sTj;          rax=_sTl
_sTp = R2;            movq %rsi,%rcx  rcx=_sTp
                      movq %rcx,64(%rsp)
_sTs = 64 - _sTl;     movl $64,%ecx
                      subq %rax,%rcx
                      movq 64(%rsp),%rdx
_sTu = _sTp >> _sTs;  shrq %cl,%rdx
                      movq %rdx,%rcx     \ 
                      movq %rcx,72(%rsp) / why?
                      movq %rax,%rcx
_sTx = _sTp << _sTl;  shlq %cl,%rdx   but rdx contains _sTp >> _sTs!
I64[Hp + (-40)] = base_GHCziWord_Wzh_con_info;
I64[Hp + (-32)] = _sTu;
I64[Hp + (-24)] = base_GHCziWord_Wzh_con_info;
I64[Hp + (-16)] = _sTx;
_sTz = _sTx | _sTu;
_sTB = _sTz;
I64[Hp + (-8)] = base_GHCziBase_Izh_con_info;
I64[Hp + 0] = _sTB;
R1 = Hp + (-8);
R2 = Hp + (-24);
R3 = Hp + (-40);
jump (I64[Sp + 0]);

Thanks Ian

Change History (7)

comment:1 Changed 11 years ago by simonmar

I think I see the bug:

    shift_code rep instr x y{-amount-} = do
        (x_reg, x_code) <- getNonClobberedReg x
        y_code <- getAnyReg y
	   code = x_code `appOL`
		  y_code ecx `snocOL`
		  instr (OpReg ecx) (OpReg x_reg)
        -- in
        return (Fixed rep x_reg code)

If getNonClobberedReg returns a Fixed reg, this code generates a shift instruction that modifies the Fixed reg, which is wrong.

However, I can't reproduce the bug locally, arith011 isn't failing in our nightly builds. Any idea why that might be?

comment:2 Changed 11 years ago by igloo

Version: 6.66.7

Do the nightly builds set -fvia-C explicitly when doing optimised builds? That's the only thing I can think of.

By the way, it's HEAD-only - forgot to set that in the original report.

Thanks Ian

comment:3 Changed 10 years ago by simonmar

Owner: set to simonmar

comment:4 Changed 10 years ago by igloo

Priority: normalhigh

comment:5 Changed 10 years ago by simonmar

Resolution: fixed
Status: newclosed


Fri May 18 12:53:30 BST 2007  Simon Marlow <>
  * FIX #1052 (NCG doesn't realise shift instructions trash shifted input)

comment:6 Changed 10 years ago by igloo

Milestone: 6.8 branch6.8.1

comment:7 Changed 4 years ago by Ian Lynagh <igloo@…>

In 11bc6605dd9bf3605fcab02afe79570c064d5047/ghc:

arith011 is broken on amd64 Linux; trac #1052
Note: See TracTickets for help on using tickets.