Andreas Klebinger pushed to branch wip/andreask/arm-ffi at Glasgow Haskell Compiler / GHC
Commits:
-
ac157837
by Andreas Klebinger at 2026-08-25T12:53:43+02:00
-
189a37c2
by Andreas Klebinger at 2026-08-25T12:53:55+02:00
12 changed files:
- compiler/GHC/Cmm/MachOp.hs
- testsuite/tests/cmm/should_compile/Makefile
- + testsuite/tests/cmm/should_compile/T27368-ppr-debug.stderr
- − testsuite/tests/cmm/should_compile/T27368-ppr-debug.stdout
- testsuite/tests/cmm/should_compile/all.T
- + testsuite/tests/codeGen/should_run/T27430.stdout
- + testsuite/tests/codeGen/should_run/T27430_c.c
- + testsuite/tests/codeGen/should_run/T27533_cmm.cmm
- + testsuite/tests/codeGen/should_run/T27537.hs
- + testsuite/tests/codeGen/should_run/T27537.stdout
- + testsuite/tests/codeGen/should_run/T27538.stdout
- testsuite/tests/codeGen/should_run/all.T
Changes:
| ... | ... | @@ -623,7 +623,9 @@ machOpArgReps platform op = |
| 623 | 623 | MO_XX_Conv from _ -> Just [from]
|
| 624 | 624 | -- Only supports W32/W64
|
| 625 | 625 | MO_SF_Round from _w -> onlyW32W64 from
|
| 626 | - MO_FS_Truncate from _ -> onlyW32W64 from
|
|
| 626 | + MO_FS_Truncate from to
|
|
| 627 | + | to `notElem` [W32, W64] -> Nothing
|
|
| 628 | + | otherwise -> onlyW32W64 from
|
|
| 627 | 629 | MO_FF_Conv from _ -> onlyW32W64 from
|
| 628 | 630 | MO_WF_Bitcast w -> onlyW32W64 w
|
| 629 | 631 | MO_FW_Bitcast w -> onlyW32W64 w
|
| ... | ... | @@ -16,16 +16,3 @@ T16930: |
| 16 | 16 | |
| 17 | 17 | T23610:
|
| 18 | 18 | '$(TEST_HC)' $(TEST_HC_OPTS) T23610.cmm -S |
| 19 | - |
|
| 20 | -# The three seds below, in order:
|
|
| 21 | -# 1. Keep only the "Parsed Cmm" dump, since that is the one stage where the
|
|
| 22 | -# unreachable block still exists.
|
|
| 23 | -# 2. Rewrite goto targets: their label uniques survive -dsuppress-uniques
|
|
| 24 | -# (#21310).
|
|
| 25 | -# 3. Drop the "// CmmAssign"-style node annotations, which pprNode emits
|
|
| 26 | -# only on DEBUG compilers.
|
|
| 27 | -T27368-ppr-debug:
|
|
| 28 | - '$(TEST_HC)' $(TEST_HC_OPTS) -c -no-hs-main -ddump-cmm-verbose-by-proc -dppr-debug -dsuppress-uniques -dsuppress-ticks T27368-ppr-debug.cmm 2>&1 \
|
|
| 29 | - | sed -n '/^==* Parsed Cmm/,/^ \}\]/p' \
|
|
| 30 | - | sed 's/goto c[0-9A-Za-z]*/goto _lbl_/g' \
|
|
| 31 | - | sed 's| *// Cmm[A-Za-z]*$$||' |
| 1 | + |
|
| 2 | +==================== Parsed Cmm ====================
|
|
| 3 | +[testUnreachable() { // [R1]
|
|
| 4 | + { info_tbls: []
|
|
| 5 | + stack_info: arg_space: 8
|
|
| 6 | + }
|
|
| 7 | + {offset
|
|
| 8 | + c7: // global
|
|
| 9 | + _c1::I64 = R1;
|
|
| 10 | + //tick src<T27368-ppr-debug.cmm:(6,1)-(19,1)>
|
|
| 11 | + if (_c1::I64 (>[W64]) 0) goto c2; else goto c4;
|
|
| 12 | + c2: // global
|
|
| 13 | + //tick src<T27368-ppr-debug.cmm:(7,14)-(9,3)>
|
|
| 14 | + goto c6;
|
|
| 15 | + c6: // global
|
|
| 16 | + //tick src<T27368-ppr-debug.cmm:17:5-12>
|
|
| 17 | + _c1::I64 = _c1::I64 (-[W64]) 1;
|
|
| 18 | + R1 = _c1::I64;
|
|
| 19 | + call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 20 | + c4: // global
|
|
| 21 | + goto c3;
|
|
| 22 | + c3: // global
|
|
| 23 | + R1 = _c1::I64;
|
|
| 24 | + call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 25 | + // unreachable blocks:
|
|
| 26 | + c5: // global
|
|
| 27 | + //tick src<T27368-ppr-debug.cmm:13:5-13>
|
|
| 28 | + _c1::I64 = _c1::I64 (+[W64]) 42;
|
|
| 29 | + R1 = _c1::I64;
|
|
| 30 | + call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 31 | + }
|
|
| 32 | + }]
|
|
| 33 | + |
|
| 34 | + |
|
| 35 | + |
|
| 36 | +==================== Post control-flow optimisations (1) ====================
|
|
| 37 | +testUnreachable
|
|
| 38 | +{offset
|
|
| 39 | + c7: // global
|
|
| 40 | + _c1::I64 = R1;
|
|
| 41 | + //tick src<T27368-ppr-debug.cmm:(6,1)-(19,1)>
|
|
| 42 | + if (_c1::I64 (>[W64]) 0) goto c2; else goto c4;
|
|
| 43 | + c2: // global
|
|
| 44 | + //tick src<T27368-ppr-debug.cmm:(7,14)-(9,3)>
|
|
| 45 | + //tick src<T27368-ppr-debug.cmm:17:5-12>
|
|
| 46 | + _c1::I64 = _c1::I64 (-[W64]) 1;
|
|
| 47 | + R1 = _c1::I64;
|
|
| 48 | + call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 49 | + c4: // global
|
|
| 50 | + R1 = _c1::I64;
|
|
| 51 | + call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 52 | +}
|
|
| 53 | + |
|
| 54 | + |
|
| 55 | + |
|
| 56 | +==================== Post switch plan ====================
|
|
| 57 | +testUnreachable
|
|
| 58 | +{offset
|
|
| 59 | + c7: // global
|
|
| 60 | + _c1::I64 = R1;
|
|
| 61 | + //tick src<T27368-ppr-debug.cmm:(6,1)-(19,1)>
|
|
| 62 | + if (_c1::I64 (>[W64]) 0) goto c2; else goto c4;
|
|
| 63 | + c2: // global
|
|
| 64 | + //tick src<T27368-ppr-debug.cmm:(7,14)-(9,3)>
|
|
| 65 | + //tick src<T27368-ppr-debug.cmm:17:5-12>
|
|
| 66 | + _c1::I64 = _c1::I64 (-[W64]) 1;
|
|
| 67 | + R1 = _c1::I64;
|
|
| 68 | + call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 69 | + c4: // global
|
|
| 70 | + R1 = _c1::I64;
|
|
| 71 | + call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 72 | +}
|
|
| 73 | + |
|
| 74 | + |
|
| 75 | + |
|
| 76 | +==================== ThreadSanitizer instrumentation ====================
|
|
| 77 | +testUnreachable
|
|
| 78 | +{offset
|
|
| 79 | + c7: // global
|
|
| 80 | + _c1::I64 = R1;
|
|
| 81 | + //tick src<T27368-ppr-debug.cmm:(6,1)-(19,1)>
|
|
| 82 | + if (_c1::I64 (>[W64]) 0) goto c2; else goto c4;
|
|
| 83 | + c2: // global
|
|
| 84 | + //tick src<T27368-ppr-debug.cmm:(7,14)-(9,3)>
|
|
| 85 | + //tick src<T27368-ppr-debug.cmm:17:5-12>
|
|
| 86 | + _c1::I64 = _c1::I64 (-[W64]) 1;
|
|
| 87 | + R1 = _c1::I64;
|
|
| 88 | + call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 89 | + c4: // global
|
|
| 90 | + R1 = _c1::I64;
|
|
| 91 | + call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 92 | +}
|
|
| 93 | + |
|
| 94 | + |
|
| 95 | + |
|
| 96 | +==================== Layout Stack ====================
|
|
| 97 | +testUnreachable
|
|
| 98 | +{offset
|
|
| 99 | + c7: // global
|
|
| 100 | + _c1::I64 = R1;
|
|
| 101 | + //tick src<T27368-ppr-debug.cmm:(6,1)-(19,1)>
|
|
| 102 | + if (_c1::I64 (>[W64]) 0) goto c2; else goto c4;
|
|
| 103 | + c2: // global
|
|
| 104 | + //tick src<T27368-ppr-debug.cmm:(7,14)-(9,3)>
|
|
| 105 | + //tick src<T27368-ppr-debug.cmm:17:5-12>
|
|
| 106 | + _c1::I64 = _c1::I64 (-[W64]) 1;
|
|
| 107 | + R1 = _c1::I64;
|
|
| 108 | + call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
|
|
| 109 | + c4: // global
|
|
| 110 | + R1 = _c1::I64;
|
|
| 111 | + call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
|
|
| 112 | +}
|
|
| 113 | + |
|
| 114 | + |
|
| 115 | + |
|
| 116 | +==================== CAFEnv ====================
|
|
| 117 | +[(c2, {}), (c4, {}), (c7, {})]
|
|
| 118 | + |
|
| 119 | + |
|
| 120 | + |
|
| 121 | +==================== after setInfoTableStackMap ====================
|
|
| 122 | +testUnreachable() { // [R1]
|
|
| 123 | + { info_tbls: []
|
|
| 124 | + stack_info: arg_space: 8
|
|
| 125 | + }
|
|
| 126 | + {offset
|
|
| 127 | + c7: // global
|
|
| 128 | + _c1::I64 = R1;
|
|
| 129 | + //tick src<T27368-ppr-debug.cmm:(6,1)-(19,1)>
|
|
| 130 | + if (_c1::I64 (>[W64]) 0) goto c2; else goto c4;
|
|
| 131 | + c2: // global
|
|
| 132 | + //tick src<T27368-ppr-debug.cmm:(7,14)-(9,3)>
|
|
| 133 | + //tick src<T27368-ppr-debug.cmm:17:5-12>
|
|
| 134 | + _c1::I64 = _c1::I64 (-[W64]) 1;
|
|
| 135 | + R1 = _c1::I64;
|
|
| 136 | + call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
|
|
| 137 | + c4: // global
|
|
| 138 | + R1 = _c1::I64;
|
|
| 139 | + call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
|
|
| 140 | + }
|
|
| 141 | +}
|
|
| 142 | + |
|
| 143 | + |
|
| 144 | + |
|
| 145 | +==================== Post control-flow optimisations (2) ====================
|
|
| 146 | +testUnreachable() { // [R1]
|
|
| 147 | + { info_tbls: []
|
|
| 148 | + stack_info: arg_space: 8
|
|
| 149 | + }
|
|
| 150 | + {offset
|
|
| 151 | + c7: // global
|
|
| 152 | + _c1::I64 = R1;
|
|
| 153 | + //tick src<T27368-ppr-debug.cmm:(6,1)-(19,1)>
|
|
| 154 | + if (_c1::I64 (>[W64]) 0) goto c2; else goto c4;
|
|
| 155 | + c2: // global
|
|
| 156 | + //tick src<T27368-ppr-debug.cmm:(7,14)-(9,3)>
|
|
| 157 | + //tick src<T27368-ppr-debug.cmm:17:5-12>
|
|
| 158 | + _c1::I64 = _c1::I64 (-[W64]) 1;
|
|
| 159 | + R1 = _c1::I64;
|
|
| 160 | + call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
|
|
| 161 | + c4: // global
|
|
| 162 | + R1 = _c1::I64;
|
|
| 163 | + call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
|
|
| 164 | + }
|
|
| 165 | +}
|
|
| 166 | + |
|
| 167 | + |
|
| 168 | + |
|
| 169 | +==================== Post CPS Cmm ====================
|
|
| 170 | +[testUnreachable() { // [R1]
|
|
| 171 | + { info_tbls: []
|
|
| 172 | + stack_info: arg_space: 8
|
|
| 173 | + }
|
|
| 174 | + {offset
|
|
| 175 | + c7: // global
|
|
| 176 | + _c1::I64 = R1;
|
|
| 177 | + //tick src<T27368-ppr-debug.cmm:(6,1)-(19,1)>
|
|
| 178 | + if (_c1::I64 (>[W64]) 0) goto c2; else goto c4;
|
|
| 179 | + c2: // global
|
|
| 180 | + //tick src<T27368-ppr-debug.cmm:(7,14)-(9,3)>
|
|
| 181 | + //tick src<T27368-ppr-debug.cmm:17:5-12>
|
|
| 182 | + _c1::I64 = _c1::I64 (-[W64]) 1;
|
|
| 183 | + R1 = _c1::I64;
|
|
| 184 | + call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
|
|
| 185 | + c4: // global
|
|
| 186 | + R1 = _c1::I64;
|
|
| 187 | + call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
|
|
| 188 | + }
|
|
| 189 | + }]
|
|
| 190 | + |
|
| 191 | + |
| 1 | -==================== Parsed Cmm ====================
|
|
| 2 | -[testUnreachable() { // [R1]
|
|
| 3 | - { info_tbls: []
|
|
| 4 | - stack_info: arg_space: 8
|
|
| 5 | - }
|
|
| 6 | - {offset
|
|
| 7 | - _lbl_:
|
|
| 8 | - __locVar_::I64 = R1;
|
|
| 9 | - if (__locVar_::I64 (>[W64]) 0) goto _lbl_; else goto _lbl_;
|
|
| 10 | - _lbl_:
|
|
| 11 | - goto _lbl_;
|
|
| 12 | - _lbl_:
|
|
| 13 | - __locVar_::I64 = __locVar_::I64 (-[W64]) 1;
|
|
| 14 | - R1 = __locVar_::I64;
|
|
| 15 | - call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 16 | - _lbl_:
|
|
| 17 | - goto _lbl_;
|
|
| 18 | - _lbl_:
|
|
| 19 | - R1 = __locVar_::I64;
|
|
| 20 | - call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 21 | - // unreachable blocks:
|
|
| 22 | - _lbl_:
|
|
| 23 | - __locVar_::I64 = __locVar_::I64 (+[W64]) 42;
|
|
| 24 | - R1 = __locVar_::I64;
|
|
| 25 | - call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
|
|
| 26 | - }
|
|
| 27 | - }] |
| ... | ... | @@ -13,11 +13,9 @@ test('T20725', normal, compile, ['-package ghc']) |
| 13 | 13 | test('T23610', normal, makefile_test, ['T23610'])
|
| 14 | 14 | test('T24224', [cmm_src, grep_errmsg(r'(F64.*);', [1]), only_ways(['normal'])], compile, ['-no-hs-main -ddump-cmm -dsuppress-all -dsuppress-uniques'])
|
| 15 | 15 | test('T24474', cmm_src, compile, ['-optc-g3'])
|
| 16 | -# -dppr-debug makes stored-but-unreachable blocks visible in Cmm dumps (#27368).
|
|
| 17 | -# Skipped on wordsize(32) targets, where the dump would say I32/P32, and on
|
|
| 18 | -# unregisterised builds, which print call targets with an extra load.
|
|
| 19 | -test('T27368-ppr-debug', [when(wordsize(32), skip), when(unregisterised(), skip)],
|
|
| 20 | - makefile_test, ['T27368-ppr-debug'])
|
|
| 16 | +# Grep for a `... = + .. 42 ..;` occurence from within the dead code block in the cmm dump output.
|
|
| 17 | +test('T27368-ppr-debug', [cmm_src, only_ways(['normal']), grep_errmsg(r'\=.*\+.*(42;)', [1])],
|
|
| 18 | + compile, ['-no-hs-main -ddump-cmm-verbose-by-proc -dppr-debug'])
|
|
| 21 | 19 | test('T24474-cmm-gets-c-opts', cmm_src, compile, ['-optc-DFOO'])
|
| 22 | 20 | test('T24474-cmm-opt-order', cmm_src, compile, ['-optc-DFOO '
|
| 23 | 21 | '-optCmmP-UFOO '
|
| 1 | +1
|
|
| 2 | +1
|
|
| 3 | +1
|
|
| 4 | +1
|
|
| 5 | +1
|
|
| 6 | +1 |
| 1 | +#include <stdint.h>
|
|
| 2 | + |
|
| 3 | +uint8_t u64_to_u8(uint64_t v) { return (uint8_t)v; }
|
|
| 4 | +uint16_t u64_to_u16(uint64_t v) { return (uint16_t)v; }
|
|
| 5 | +uint32_t u64_to_u32(uint64_t v) { return (uint32_t)v; } |
| 1 | +#include "Cmm.h"
|
|
| 2 | + |
|
| 3 | +// Release-store one byte at p. Must touch exactly 1 byte.
|
|
| 4 | +store8 (W_ p) {
|
|
| 5 | + %release I8[p] = 67 :: I8;
|
|
| 6 | + return (0);
|
|
| 7 | +}
|
|
| 8 | + |
|
| 9 | +// Acquire-load one byte from p.
|
|
| 10 | +load8 (W_ p) {
|
|
| 11 | + I8 v;
|
|
| 12 | + v = %acquire I8[p];
|
|
| 13 | + return (TO_ZXW_(v));
|
|
| 14 | +} |
| 1 | +{-# LANGUAGE MagicHash #-}
|
|
| 2 | + |
|
| 3 | +import GHC.Exts
|
|
| 4 | + |
|
| 5 | +{-# NOINLINE lt8 #-}
|
|
| 6 | +lt8 :: Int -> Word -> Int -- ltWord8# 254 255: must be 1
|
|
| 7 | +lt8 (I# m) (W# n) = I# (ltWord8# (int8ToWord8# (intToInt8# m)) (wordToWord8# n))
|
|
| 8 | + |
|
| 9 | +{-# NOINLINE eq8 #-}
|
|
| 10 | +eq8 :: Int -> Word -> Int -- eqWord8# 254 254: must be 1
|
|
| 11 | +eq8 (I# m) (W# n) = I# (eqWord8# (int8ToWord8# (intToInt8# m)) (wordToWord8# n))
|
|
| 12 | + |
|
| 13 | +{-# NOINLINE eqi16 #-}
|
|
| 14 | +eqi16 :: Int -> Int -> Int -- eqInt16# (-2) (-2): must be 1
|
|
| 15 | +eqi16 (I# m) (I# n) = I# (eqInt16# (intToInt16# m) (word16ToInt16# (wordToWord16# (int2Word# n))))
|
|
| 16 | + |
|
| 17 | +{-# NOINLINE rem8 #-}
|
|
| 18 | +rem8 :: Int -> Word -> Word -- remWord8# 254 100: must be 54
|
|
| 19 | +rem8 (I# m) (W# n) = W# (word8ToWord# (remWord8# (int8ToWord8# (intToInt8# m)) (wordToWord8# n)))
|
|
| 20 | + |
|
| 21 | +main :: IO ()
|
|
| 22 | +main = do
|
|
| 23 | + print (lt8 (-2) 255)
|
|
| 24 | + print (eq8 (-2) 254)
|
|
| 25 | + print (eqi16 (-2) 65534)
|
|
| 26 | + print (rem8 (-2) 100) |
| 1 | +1
|
|
| 2 | +1
|
|
| 3 | +1
|
|
| 4 | +54 |
| 1 | +f(0x80) = 0 |
| ... | ... | @@ -295,3 +295,12 @@ test('aarch64-sxtw-run', |
| 295 | 295 | when(unregisterised(), skip)],
|
| 296 | 296 | multi_compile_and_run,
|
| 297 | 297 | ['aarch64-sxtw-run', [('aarch64-sxtw-cmm.cmm', '')], '-O'])
|
| 298 | + |
|
| 299 | +test('T27430', [req_c, extra_ways(['optasm'])], compile_and_run, ['T27430_c.c'])
|
|
| 300 | + |
|
| 301 | +test('T27533', [req_cmm, extra_ways(['optasm'])], multi_compile_and_run,
|
|
| 302 | + ['T27533', [('T27533_cmm.cmm', '')], '-O'])
|
|
| 303 | + |
|
| 304 | +test('T27537', normal, compile_and_run, ['-O'])
|
|
| 305 | + |
|
| 306 | +test('T27538', normal, compile_and_run, ['-O']) |