summaryrefslogtreecommitdiff
path: root/compiler/nativeGen
diff options
context:
space:
mode:
authorReid Barton <rwbarton@gmail.com>2017-03-23 21:02:29 -0400
committerBen Gamari <ben@smart-cactus.org>2017-03-24 10:14:26 -0400
commitcaf94b062a0e37ffa7048e51447fc9486b658917 (patch)
treed14fdcbcbdf3844ae80dbe423396d825974bbe4e /compiler/nativeGen
parent8429a202ec8aef0af226d3fb5907b47dc9cba155 (diff)
downloadhaskell-caf94b062a0e37ffa7048e51447fc9486b658917.tar.gz
x86 nativeGen: Fix test with mask in range [128,255] (#13425)
My commit bdb0c43c7 optimized the encoding of instructions to test tag bits, but it did not always set exactly the same condition codes since the testb instruction does a single-byte comparison, rather than a full-word comparison. It would be correct to optimize the expression `x .&. 128 > 0` to the sequence testb $128, %al seta %al ; note: 'a' for unsigned comparison, ; not 'g' for signed comparison but the pretty-printer is not the right place to make this kind of context-sensitive optimization. Test Plan: harbormaster Reviewers: trofi, austin, bgamari, dfeuer Reviewed By: trofi, dfeuer Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D3359
Diffstat (limited to 'compiler/nativeGen')
-rw-r--r--compiler/nativeGen/X86/Ppr.hs6
1 files changed, 5 insertions, 1 deletions
diff --git a/compiler/nativeGen/X86/Ppr.hs b/compiler/nativeGen/X86/Ppr.hs
index 7d19e990ce..5044c83c89 100644
--- a/compiler/nativeGen/X86/Ppr.hs
+++ b/compiler/nativeGen/X86/Ppr.hs
@@ -671,8 +671,12 @@ pprInstr (TEST format src dst) = sdocWithPlatform $ \platform ->
-- (We could handle masks larger than a single byte too,
-- but it would complicate the code considerably
-- and tag checks are by far the most common case.)
+ -- The mask must have the high bit clear for this smaller encoding
+ -- to be completely equivalent to the original; in particular so
+ -- that the signed comparison condition bits are the same as they
+ -- would be if doing a full word comparison. See Trac #13425.
(OpImm (ImmInteger mask), OpReg dstReg)
- | 0 <= mask && mask < 256 -> minSizeOfReg platform dstReg
+ | 0 <= mask && mask < 128 -> minSizeOfReg platform dstReg
_ -> format
in pprFormatOpOp (sLit "test") format' src dst
where