[llvm-dev] question about flag register through instruction selection and instruction scheduling
林政宗 via llvm-dev
llvm-dev at lists.llvm.org
Sun May 30 19:48:34 PDT 2021
Hi,
I am trying to support addition of int64 on my target which has only 32 bit registers.
The target has only normal add instruction which adds two 32 bit register, writes result to a register, and updates carry flag in flag regitser.
It does not have the addwithcarry instruction which adds two register and carry flag, writes result to a register, and updates carry flag.
I have refered to the implementation of 64bit addition on cortex-a7 which is arm architecture and have some questions.
the c source, .ll file, and debug dump is attached.
-----------------------------------------debug dump-------------------------------------------------------------
1522Optimized legalized selection DAG: %bb.0 'foo:entry'
1523SelectionDAG has 16 nodes:
1524 t0: ch = EntryToken
1525 t17: ch,glue = CopyToReg t0, Register:i32 $r0, t29
1526 t8: i32,ch = CopyFromReg t0, Register:i32 %3
1527 t4: i32,ch = CopyFromReg t0, Register:i32 %1
1528 t25: i32,i32 = ARMISD::ADDE t8, t4, t29:1
1529 t19: ch,glue = CopyToReg t17, Register:i32 $r1, t25, t17:1
1530 t6: i32,ch = CopyFromReg t0, Register:i32 %2
1531 t2: i32,ch = CopyFromReg t0, Register:i32 %0
1532 t29: i32,i32 = ARMISD::ADDC t6, t2
1533 t20: ch = ARMISD::RET_FLAG t19, Register:i32 $r0, Register:i32 $r1, t19:1
---------------------------------------------------------------------------------------------------------------------
Question 1:
In the lowering process, arm cortex-a7 simulate the carry flag by considering it as data dependence, such as t25: i32,i32 = ARMISD::ADDE t8, t4, t29:1.
Is it safer by simulate the carry flag by using a MVT::Glue?
If the DAG graph is large and we see it as data dependence, is it possible that an other instruction is inserted between the two nodes/instructions, which have carry flag dependence, after emitting schedule in CodeGenAndEmitDAG()(SelectionDAGISel.cpp)?
If the inserted instruction happens to update the carry flag, the second ARMISD::ADDE will have incorrect result. Or is it guaranteed the case will not happen?
------------------------------------debug dump-----------------------------------------------------------------
1548ISEL: Starting selection on root node: t25: i32,i32 = ARMISD::ADDE t8, t4, t29:1
1549ISEL: Starting pattern match
1550 Initial Opcode index to 94735
1551 Match failed at index 94748
1552 Continuing at 94777
1553 Match failed at index 94778
1554 Continuing at 94806
1555 Continuing at 94807
1556 Match failed at index 94808
1557 Continuing at 94838
1558 Continuing at 94839
1559 Match failed at index 94842
1560 Continuing at 95134
1561Creating new node: t35: ch,glue = CopyToReg t0, Register:i32 $cpsr, t29:1
1562 Morphed node: t25: i32,i32 = ADCrr t8, t4, TargetConstant:i32<14>, Register:i32 $noreg, Register:i32 $noreg, t35:1
1563ISEL: Match complete!
----------------------------------td file(ARMInstrInfo.td)-------------------------------------------------------------------------------
3717let isAdd = 1 in
3718defm ADC : AI1_adde_sube_irs<0b0101, "adc", ARMadde, 1>;
1740/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
1741let TwoOperandAliasConstraint = "$Rn = $Rd" in
1742multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, SDNode opnode,
1743 bit Commutable = 0> {
1744 let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in {
1745 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm),
1746 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
1747 [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, mod_imm:$imm, CPSR))]>,
1748 Requires<[IsARM]>,
1749 Sched<[WriteALU, ReadALU]> {
1750 bits<4> Rd;
1751 bits<4> Rn;
1752 bits<12> imm;
1753 let Inst{25} = 1;
1754 let Inst{15-12} = Rd;
1755 let Inst{19-16} = Rn;
1756 let Inst{11-0} = imm;
1757 }
1758 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
1759 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
1760 [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm, CPSR))]>,
1761 Requires<[IsARM]>,
1762 Sched<[WriteALU, ReadALU, ReadALU]> {
1763 bits<4> Rd;
1764 bits<4> Rn;
1765 bits<4> Rm;
1766 let Inst{11-4} = 0b00000000;
1767 let Inst{25} = 0;
1768 let isCommutable = Commutable;
1769 let Inst{3-0} = Rm;
1770 let Inst{15-12} = Rd;
1771 let Inst{19-16} = Rn;
1772 }
-------------------------------------------------------------------------------------------------------------------------------------------
Question 2:
When selecting ARMISD::ADDE, a new node(t35) is created. Why does tablegen create a new node?
Is this behavior related with the code "(opnode GPR:$Rn, GPR:$Rm, CPSR))" at line 1760?
Is it because CPSR is a parameter of opnode?
---------------------------------------------debug dump------------------------------------------------------------------------------
1812Total amount of phi nodes to update: 0
1813*** MachineFunction at end of ISel ***
1814# Machine code for function foo: IsSSA, TracksLiveness
1815Function Live Ins: $r0 in %0, $r1 in %1, $r2 in %2, $r3 in %3
1816
1817bb.0.entry:
1818 liveins: $r0, $r1, $r2, $r3
1819 %3:gpr = COPY $r3
1820 %2:gpr = COPY $r2
1821 %1:gpr = COPY $r1
1822 %0:gpr = COPY $r0
1823 %4:gpr = ADDrr %2:gpr, %0:gpr, 14, $noreg, def $cpsr
1824 %5:gpr = ADCrr %3:gpr, %1:gpr, 14, $noreg, $noreg, implicit $cpsr
1825 $r0 = COPY %4:gpr
1826 $r1 = COPY %5:gpr
1827 BX_RET 14, $noreg, implicit $r0, implicit $r1
1828
1829# End machine code for function foo.
-----------------------------------------------------------------------------------------------------------------------------------------------
Question 3:
if the basic block bb.0.entry has a lot of instructions and Machine Instruction Scheduler is enabled, the instruciton sequence will be reordered by latency.
Is it possible that an other instruction is placed between ADDrr and ADCrr?
If the placed instruction happens to update carry flag, We will get incorrect result.
Thanks,
Jerry
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210531/8cc53384/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.arm.debug
Type: application/octet-stream
Size: 89545 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210531/8cc53384/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.arm.ll
Type: application/octet-stream
Size: 1380 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210531/8cc53384/attachment-0003.obj>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: test.c
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210531/8cc53384/attachment-0001.c>
More information about the llvm-dev
mailing list