... |
... |
@@ -395,26 +395,28 @@ cmmMachOpFoldM platform mop [x, (CmmLit (CmmInt 1 rep))] |
395
|
395
|
one = CmmLit (CmmInt 1 (wordWidth platform))
|
396
|
396
|
|
397
|
397
|
-- Now look for multiplication/division by powers of 2 (integers).
|
398
|
|
-
|
399
|
|
-cmmMachOpFoldM platform mop [x, (CmmLit (CmmInt n w))]
|
|
398
|
+--
|
|
399
|
+-- ToDo: See #25664 (comment 605821) describing a change to the Cmm literal representation.
|
|
400
|
+-- When/If this is completed, this code must be refactored to account for the explicit width sizes.
|
|
401
|
+cmmMachOpFoldM platform mop [x, (CmmLit (CmmInt n _))]
|
400
|
402
|
= case mop of
|
401
|
403
|
MO_Mul rep
|
402
|
|
- | Just p <- widthBoundedExactLog2 False w n ->
|
|
404
|
+ | Just p <- exactLog2 (narrowU rep n) ->
|
403
|
405
|
Just $! (cmmMachOpFold platform (MO_Shl rep) [x, CmmLit (CmmInt p $ wordWidth platform)])
|
404
|
406
|
MO_U_Quot rep
|
405
|
|
- | Just p <- widthBoundedExactLog2 False w n ->
|
|
407
|
+ | Just p <- exactLog2 (narrowU rep n) ->
|
406
|
408
|
Just $! (cmmMachOpFold platform (MO_U_Shr rep) [x, CmmLit (CmmInt p $ wordWidth platform)])
|
407
|
409
|
MO_U_Rem rep
|
408
|
|
- | Just _ <- widthBoundedExactLog2 False w n ->
|
|
410
|
+ | Just _ <- exactLog2 (narrowU rep n) ->
|
409
|
411
|
Just $! (cmmMachOpFold platform (MO_And rep) [x, CmmLit (CmmInt (n - 1) rep)])
|
410
|
412
|
MO_S_Quot rep
|
411
|
|
- | Just p <- widthBoundedExactLog2 True w n,
|
|
413
|
+ | Just p <- exactLog2 (narrowS rep n),
|
412
|
414
|
CmmReg _ <- x -> -- We duplicate x in signedQuotRemHelper, hence require
|
413
|
415
|
-- it is a reg. FIXME: remove this restriction.
|
414
|
416
|
Just $! (cmmMachOpFold platform (MO_S_Shr rep)
|
415
|
417
|
[signedQuotRemHelper rep p, CmmLit (CmmInt p $ wordWidth platform)])
|
416
|
418
|
MO_S_Rem rep
|
417
|
|
- | Just p <- widthBoundedExactLog2 True w n,
|
|
419
|
+ | Just p <- exactLog2 (narrowS rep n),
|
418
|
420
|
CmmReg _ <- x -> -- We duplicate x in signedQuotRemHelper, hence require
|
419
|
421
|
-- it is a reg. FIXME: remove this restriction.
|
420
|
422
|
-- We replace (x `rem` 2^p) by (x - (x `quot` 2^p) * 2^p).
|
... |
... |
@@ -449,14 +451,6 @@ cmmMachOpFoldM platform mop [x, (CmmLit (CmmInt n w))] |
449
|
451
|
x1 = CmmMachOp shr [x, CmmLit (CmmInt bits $ wordWidth platform)]
|
450
|
452
|
x2 = if p == 1 then x1 else
|
451
|
453
|
CmmMachOp (MO_And rep) [x1, CmmLit (CmmInt (n-1) rep)]
|
452
|
|
- -- Determine if the input is an exact power of 2 AND within the logical range
|
453
|
|
- -- of values permited by the bit-width. Without this check, the bit shifting
|
454
|
|
- -- operations to multiply/divide by oowers of 2 may be unsound and result in
|
455
|
|
- -- incorrect runtime results.
|
456
|
|
- widthBoundedExactLog2 :: Bool -> Width -> Integer -> Maybe Integer
|
457
|
|
- widthBoundedExactLog2 signed rep v = case exactLog2 v of
|
458
|
|
- Just p | p >= fromIntegral (widthInBits rep - fromEnum signed) -> Nothing
|
459
|
|
- m -> m
|
460
|
454
|
|
461
|
455
|
-- ToDo (#7116): optimise floating-point multiplication, e.g. x*2.0 -> x+x
|
462
|
456
|
-- Unfortunately this needs a unique supply because x might not be a
|