https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118934
--- Comment #6 from liu mirko <lw297073896 at gmail dot com> --- (In reply to liu mirko from comment #5) > (In reply to Jeffrey A. Law from comment #4) > > This should be fixed on the trunk. > > int foo(int x) > { > if (x) > goto out; > > // > 1MB of code > INSNS_524288 > > out: > return x; > } > > if "INSNS_524288" is replaced with "asm volatile("nop;nop;....Repeat A > multiple times");" and the assembly code of nop exceeds 1MB, the problem may > still persist. sorry, the above case does not encounter linking issues with "nop;", but problems arise when using the pseudo-instruction "li t5,0x180000000;" in "asm volatile" (which actually maps to two instructions with a length of 6 bytes). In the md file: ``` ;; Length of instruction in bytes. (define_attr "length" "" (cond [ ;; Branches further than +/- 1 MiB require three instructions. ;; Branches further than +/- 4 KiB require two instructions. (eq_attr "type" "branch") (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088)) (le (minus (pc) (match_dup 0)) (const_int 4092))) (const_int 4) (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 1048568)) (le (minus (pc) (match_dup 0)) (const_int 1048572))) (const_int 8) (const_int 12))) ;; Jumps further than +/- 1 MiB require two instructions. (eq_attr "type" "jump") (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 1048568)) (le (minus (pc) (match_dup 0)) (const_int 1048572))) (const_int 4) (const_int 8)) ;; Conservatively assume calls take two instructions (AUIPC + JALR). ;; The linker will opportunistically relax the sequence to JAL. (eq_attr "type" "call") (const_int 8) ;; "Ghost" instructions occupy no space. (eq_attr "type" "ghost") (const_int 0) (eq_attr "got" "load") (const_int 8) ;; SHIFT_SHIFTs are decomposed into two separate instructions. (eq_attr "move_type" "shift_shift") (const_int 8) ;; Check for doubleword moves that are decomposed into two ;; instructions. (and (eq_attr "move_type" "mtc,mfc,move") (eq_attr "dword_mode" "yes")) (const_int 8) ;; Doubleword CONST{,N} moves are split into two word ;; CONST{,N} moves. (and (eq_attr "move_type" "const") (eq_attr "dword_mode" "yes")) (symbol_ref "riscv_split_const_insns (operands[1]) * 4") ;; Otherwise, constants, loads and stores are handled by external ;; routines. (eq_attr "move_type" "load,fpload") (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4") (eq_attr "move_type" "store,fpstore") (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4") ] (const_int 4))) ``` the "length" of an assembly instruction is 4, leading to incorrect judgment of the instruction length in "asm volatile".