[Bug target/61503] New: RTL representation of i386 shrdl instruction is incorrect?
nirhasabnis at gmail dot com
gcc-bugzilla@gcc.gnu.org
Fri Jun 13 16:50:00 GMT 2014
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61503
Bug ID: 61503
Summary: RTL representation of i386 shrdl instruction is
incorrect?
Product: gcc
Version: 4.10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: nirhasabnis at gmail dot com
Hello,
I was studying i386 machine description for my research purpose,
and I stumbled upon following MD entry for 'shrdl' x86 instruction.
It is obtained from the most recent i386.md file.
(define_insn "x86_shrd"
[(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
(ior:SI (ashiftrt:SI (match_dup 0)
(match_operand:QI 2 "nonmemory_operand" "Ic"))
(ashift:SI (match_operand:SI 1 "register_operand" "r")
(minus:QI (const_int 32) (match_dup 2)))))
(clobber (reg:CC FLAGS_REG))]
""
"shrd{l}\t{%s2%1, %0|%0, %1, %2}"
[(set_attr "type" "ishift")
(set_attr "prefix_0f" "1")
(set_attr "mode" "SI")
(set_attr "pent_pair" "np")
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "vector")
(set_attr "bdver1_decode" "vector")])
It seems to me that the RTL representation for 'shrdl' is incorrect.
Semantics of shrdl instruction as per Intel manual is:
"The instruction shifts the first operand (destination operand) to the right
the number of bits specified by the third operand (count operand).
The second operand (source operand) provides bits to shift in from the
left (starting with the most significant bit of the destination operand)."
And the way RTL does it is by inclusive-or of arithmetically
right-shifted destination and left-shifted source operand.
But the problem is that: in case of a destination (reg/mem) containing
negative value, arithmetically right-shifted destination will have top bits
set to 1. Inclusive-or with such a value is going to generate a
result with top bits set to 1 instead of moving contents of source
into top bits of destination.
E.g., when ebx = b72f60d0, ebp = bfcbd2c8
shrdl $16, %ebp, %ebx (ebx is dest, ebp is src)
produces 0xd2c8b72f in ebx.
But the corresponding RTL produces 0xffffb72f in ebx.
So it seems to me that instead of 'ashiftrt', RTL should have 'lshiftrt'.
Filing a bug as per the discussion at
https://gcc.gnu.org/ml/gcc/2014-06/msg00070.html
More information about the Gcc-bugs
mailing list