While working with a patch for instruction selection a splitting of a large immediate ended up treated incorrectly by the backend. Where a register operand should have been created, instead it became an immediate. The 3-address instruction was created like
<REG0> = <IMM>, <REG2>,
which is obviously wrong. To my surprise, the machine verifier failed to report this! I don't know why, but I certainly think it should have, so I made a little patch to improve it. While at it, I also added the inverse check for when the MachineOperand is a register, but the descriptor says it should be an immediate.
These tests now fail:
Mips: micromips-sw.ll, tailcall/tailcall.ll:
*** Bad machine code: Expected a register operand. *** - function: caller1 - basic block: %bb.0 entry (0x5df9a58) - instruction: JALRC16_MMR6 @callee1, <regmask $fp $ra $f20 $f22 $f24 $f26 $f28 $f30 $f_hi20 $f_hi22 $f_hi24 $f_hi26 $f_hi28 $f_hi30 $s0 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $d20_64 $d22_64 $d24_64 $d26_64 $d28_64 $d30_64>, implicit-def dead $ra, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implici\ t-def $sp, implicit-def $v0 - operand 0: @callee1
@callee1 is a MO_GlobalAddress, but OperandType is OPERAND_REGISTER.
Hexagon/sdr-global.mir fails in the same way:
*** Bad machine code: Expected a register operand. *** - function: fred - basic block: %bb.0 (0x5d405d8) - instruction: %0:doubleregs = A4_combineir 0, @g0 - operand 2: @g0
Hexagon/expand-condsets-phys-reg.mir fails with an immediate instead of a reg:
*** Bad machine code: Expected a register operand. *** - function: fred - basic block: %bb.0 (0x5d401c8) - instruction: %1:predregs = C2_cmplt %0:intregs, 10 - operand 2: 10
DebugInfo/X86/live-debug-vars-discard-invalid.mir:
*** Bad machine code: Expected a register operand. *** - function: foobar - basic block: %bb.4 (0x5d755a8) - instruction: %1:gr64 = BTS64rr %1:gr64(tied-def 0), 0, implicit-def $eflags - operand 2: 0
The new test case test/MachineVerifier/verify-targetops.mir is a small function with purposefully corrupted operands. In addition to the two errors that are checked for, this is actually also reported:
*** Bad machine code: Tied use must be a register *** - function: fun - basic block: %bb.0 (0x5d7fa88) - instruction: %1:gr32 = XOR32rm -1, %fixed-stack.1, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load 4 from %fixed-stack.1, align 8) - operand 1: -1
Not sure if that matters (what is a 3-address instruction that would serve well here?)...
Do you really need this check? I would expect this to work naturally with generic instruction operands