llvm.org GIT mirror llvm / 4e92383
[MachineCombiner][AArch64] Use the correct register class for MADD, SUB, and OR. Select the correct register class for the various instructions that are generated when combining instructions and constrain the registers to the appropriate register class. This fixes rdar://problem/18183707. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216805 91177308-0d34-0410-b5e6-96231b3b80d8 Juergen Ributzka 6 years ago
2 changed file(s) with 146 addition(s) and 80 deletion(s). Raw diff Collapse all Expand all
24252425 static MachineInstr *genMadd(MachineFunction &MF, MachineRegisterInfo &MRI,
24262426 const TargetInstrInfo *TII, MachineInstr &Root,
24272427 SmallVectorImpl &InsInstrs,
2428 unsigned IdxMulOpd, unsigned MaddOpc) {
2428 unsigned IdxMulOpd, unsigned MaddOpc,
2429 const TargetRegisterClass *RC) {
24292430 assert(IdxMulOpd == 1 || IdxMulOpd == 2);
24302431
24312432 unsigned IdxOtherOpd = IdxMulOpd == 1 ? 2 : 1;
24322433 MachineInstr *MUL = MRI.getUniqueVRegDef(Root.getOperand(IdxMulOpd).getReg());
2433 MachineOperand R = Root.getOperand(0);
2434 MachineOperand A = MUL->getOperand(1);
2435 MachineOperand B = MUL->getOperand(2);
2436 MachineOperand C = Root.getOperand(IdxOtherOpd);
2437 MachineInstrBuilder MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc))
2438 .addOperand(R)
2439 .addOperand(A)
2440 .addOperand(B)
2441 .addOperand(C);
2434 unsigned ResultReg = Root.getOperand(0).getReg();
2435 unsigned SrcReg0 = MUL->getOperand(1).getReg();
2436 bool Src0IsKill = MUL->getOperand(1).isKill();
2437 unsigned SrcReg1 = MUL->getOperand(2).getReg();
2438 bool Src1IsKill = MUL->getOperand(2).isKill();
2439 unsigned SrcReg2 = Root.getOperand(IdxOtherOpd).getReg();
2440 bool Src2IsKill = Root.getOperand(IdxOtherOpd).isKill();
2441
2442 if (TargetRegisterInfo::isVirtualRegister(ResultReg))
2443 MRI.constrainRegClass(ResultReg, RC);
2444 if (TargetRegisterInfo::isVirtualRegister(SrcReg0))
2445 MRI.constrainRegClass(SrcReg0, RC);
2446 if (TargetRegisterInfo::isVirtualRegister(SrcReg1))
2447 MRI.constrainRegClass(SrcReg1, RC);
2448 if (TargetRegisterInfo::isVirtualRegister(SrcReg2))
2449 MRI.constrainRegClass(SrcReg2, RC);
2450
2451 MachineInstrBuilder MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc),
2452 ResultReg)
2453 .addReg(SrcReg0, getKillRegState(Src0IsKill))
2454 .addReg(SrcReg1, getKillRegState(Src1IsKill))
2455 .addReg(SrcReg2, getKillRegState(Src2IsKill));
24422456 // Insert the MADD
24432457 InsInstrs.push_back(MIB);
24442458 return MUL;
24632477 const TargetInstrInfo *TII, MachineInstr &Root,
24642478 SmallVectorImpl &InsInstrs,
24652479 unsigned IdxMulOpd, unsigned MaddOpc,
2466 unsigned VR) {
2480 unsigned VR, const TargetRegisterClass *RC) {
24672481 assert(IdxMulOpd == 1 || IdxMulOpd == 2);
24682482
24692483 MachineInstr *MUL = MRI.getUniqueVRegDef(Root.getOperand(IdxMulOpd).getReg());
2470 MachineOperand R = Root.getOperand(0);
2471 MachineOperand A = MUL->getOperand(1);
2472 MachineOperand B = MUL->getOperand(2);
2473 MachineInstrBuilder MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc))
2474 .addOperand(R)
2475 .addOperand(A)
2476 .addOperand(B)
2484 unsigned ResultReg = Root.getOperand(0).getReg();
2485 unsigned SrcReg0 = MUL->getOperand(1).getReg();
2486 bool Src0IsKill = MUL->getOperand(1).isKill();
2487 unsigned SrcReg1 = MUL->getOperand(2).getReg();
2488 bool Src1IsKill = MUL->getOperand(2).isKill();
2489
2490 if (TargetRegisterInfo::isVirtualRegister(ResultReg))
2491 MRI.constrainRegClass(ResultReg, RC);
2492 if (TargetRegisterInfo::isVirtualRegister(SrcReg0))
2493 MRI.constrainRegClass(SrcReg0, RC);
2494 if (TargetRegisterInfo::isVirtualRegister(SrcReg1))
2495 MRI.constrainRegClass(SrcReg1, RC);
2496 if (TargetRegisterInfo::isVirtualRegister(VR))
2497 MRI.constrainRegClass(VR, RC);
2498
2499 MachineInstrBuilder MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc),
2500 ResultReg)
2501 .addReg(SrcReg0, getKillRegState(Src0IsKill))
2502 .addReg(SrcReg1, getKillRegState(Src1IsKill))
24772503 .addReg(VR);
24782504 // Insert the MADD
24792505 InsInstrs.push_back(MIB);
24802506 return MUL;
24812507 }
2508
24822509 /// genAlternativeCodeSequence - when hasPattern() finds a pattern
24832510 /// this function generates the instructions that could replace the
24842511 /// original code sequence
24932520 const TargetInstrInfo *TII = MF.getTarget().getSubtargetImpl()->getInstrInfo();
24942521
24952522 MachineInstr *MUL;
2523 const TargetRegisterClass *RC = nullptr;
24962524 unsigned Opc;
24972525 switch (Pattern) {
24982526 default:
25062534 // --- Create(MADD);
25072535 Opc = Pattern == MachineCombinerPattern::MC_MULADDW_OP1 ? AArch64::MADDWrrr
25082536 : AArch64::MADDXrrr;
2509 MUL = genMadd(MF, MRI, TII, Root, InsInstrs, 1, Opc);
2537 if (Pattern == MachineCombinerPattern::MC_MULADDW_OP1)
2538 RC = &AArch64::GPR32RegClass;
2539 else
2540 RC = &AArch64::GPR64RegClass;
2541 MUL = genMadd(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC);
25102542 break;
25112543 case MachineCombinerPattern::MC_MULADDW_OP2:
25122544 case MachineCombinerPattern::MC_MULADDX_OP2:
25162548 // --- Create(MADD);
25172549 Opc = Pattern == MachineCombinerPattern::MC_MULADDW_OP2 ? AArch64::MADDWrrr
25182550 : AArch64::MADDXrrr;
2519 MUL = genMadd(MF, MRI, TII, Root, InsInstrs, 2, Opc);
2551 if (Pattern == MachineCombinerPattern::MC_MULADDW_OP2)
2552 RC = &AArch64::GPR32RegClass;
2553 else
2554 RC = &AArch64::GPR64RegClass;
2555 MUL = genMadd(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC);
25202556 break;
25212557 case MachineCombinerPattern::MC_MULADDWI_OP1:
2522 case MachineCombinerPattern::MC_MULADDXI_OP1:
2558 case MachineCombinerPattern::MC_MULADDXI_OP1: {
25232559 // MUL I=A,B,0
25242560 // ADD R,I,Imm
25252561 // ==> ORR V, ZR, Imm
25262562 // ==> MADD R,A,B,V
25272563 // --- Create(MADD);
2528 {
2529 const TargetRegisterClass *RC =
2530 MRI.getRegClass(Root.getOperand(1).getReg());
2531 unsigned NewVR = MRI.createVirtualRegister(RC);
2532 unsigned BitSize, OrrOpc, ZeroReg;
2533 if (Pattern == MachineCombinerPattern::MC_MULADDWI_OP1) {
2534 BitSize = 32;
2535 OrrOpc = AArch64::ORRWri;
2536 ZeroReg = AArch64::WZR;
2537 Opc = AArch64::MADDWrrr;
2538 } else {
2539 OrrOpc = AArch64::ORRXri;
2540 BitSize = 64;
2541 ZeroReg = AArch64::XZR;
2542 Opc = AArch64::MADDXrrr;
2543 }
2544 uint64_t Imm = Root.getOperand(2).getImm();
2545
2546 if (Root.getOperand(3).isImm()) {
2547 unsigned val = Root.getOperand(3).getImm();
2548 Imm = Imm << val;
2549 }
2550 uint64_t UImm = Imm << (64 - BitSize) >> (64 - BitSize);
2551 uint64_t Encoding;
2552
2553 if (AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding)) {
2554 MachineInstrBuilder MIB1 =
2555 BuildMI(MF, Root.getDebugLoc(), TII->get(OrrOpc))
2556 .addOperand(MachineOperand::CreateReg(NewVR, true))
2557 .addReg(ZeroReg)
2558 .addImm(Encoding);
2559 InsInstrs.push_back(MIB1);
2560 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0));
2561 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR);
2562 }
2563 }
2564 break;
2564 const TargetRegisterClass *OrrRC = nullptr;
2565 unsigned BitSize, OrrOpc, ZeroReg;
2566 if (Pattern == MachineCombinerPattern::MC_MULADDWI_OP1) {
2567 OrrOpc = AArch64::ORRWri;
2568 OrrRC = &AArch64::GPR32spRegClass;
2569 BitSize = 32;
2570 ZeroReg = AArch64::WZR;
2571 Opc = AArch64::MADDWrrr;
2572 RC = &AArch64::GPR32RegClass;
2573 } else {
2574 OrrOpc = AArch64::ORRXri;
2575 OrrRC = &AArch64::GPR64spRegClass;
2576 BitSize = 64;
2577 ZeroReg = AArch64::XZR;
2578 Opc = AArch64::MADDXrrr;
2579 RC = &AArch64::GPR64RegClass;
2580 }
2581 unsigned NewVR = MRI.createVirtualRegister(OrrRC);
2582 uint64_t Imm = Root.getOperand(2).getImm();
2583
2584 if (Root.getOperand(3).isImm()) {
2585 unsigned Val = Root.getOperand(3).getImm();
2586 Imm = Imm << Val;
2587 }
2588 uint64_t UImm = Imm << (64 - BitSize) >> (64 - BitSize);
2589 uint64_t Encoding;
2590 if (AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding)) {
2591 MachineInstrBuilder MIB1 =
2592 BuildMI(MF, Root.getDebugLoc(), TII->get(OrrOpc), NewVR)
2593 .addReg(ZeroReg)
2594 .addImm(Encoding);
2595 InsInstrs.push_back(MIB1);
2596 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0));
2597 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC);
2598 }
2599 break;
2600 }
25652601 case MachineCombinerPattern::MC_MULSUBW_OP1:
25662602 case MachineCombinerPattern::MC_MULSUBX_OP1: {
25672603 // MUL I=A,B,0
25692605 // ==> SUB V, 0, C
25702606 // ==> MADD R,A,B,V // = -C + A*B
25712607 // --- Create(MADD);
2572 const TargetRegisterClass *RC =
2573 MRI.getRegClass(Root.getOperand(1).getReg());
2574 unsigned NewVR = MRI.createVirtualRegister(RC);
2608 const TargetRegisterClass *SubRC = nullptr;
25752609 unsigned SubOpc, ZeroReg;
25762610 if (Pattern == MachineCombinerPattern::MC_MULSUBW_OP1) {
25772611 SubOpc = AArch64::SUBWrr;
2612 SubRC = &AArch64::GPR32spRegClass;
25782613 ZeroReg = AArch64::WZR;
25792614 Opc = AArch64::MADDWrrr;
2615 RC = &AArch64::GPR32RegClass;
25802616 } else {
25812617 SubOpc = AArch64::SUBXrr;
2618 SubRC = &AArch64::GPR64spRegClass;
25822619 ZeroReg = AArch64::XZR;
25832620 Opc = AArch64::MADDXrrr;
2584 }
2621 RC = &AArch64::GPR64RegClass;
2622 }
2623 unsigned NewVR = MRI.createVirtualRegister(SubRC);
25852624 // SUB NewVR, 0, C
25862625 MachineInstrBuilder MIB1 =
2587 BuildMI(MF, Root.getDebugLoc(), TII->get(SubOpc))
2588 .addOperand(MachineOperand::CreateReg(NewVR, true))
2626 BuildMI(MF, Root.getDebugLoc(), TII->get(SubOpc), NewVR)
25892627 .addReg(ZeroReg)
25902628 .addOperand(Root.getOperand(2));
25912629 InsInstrs.push_back(MIB1);
25922630 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0));
2593 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR);
2594 } break;
2631 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC);
2632 break;
2633 }
25952634 case MachineCombinerPattern::MC_MULSUBW_OP2:
25962635 case MachineCombinerPattern::MC_MULSUBX_OP2:
25972636 // MUL I=A,B,0
26002639 // --- Create(MSUB);
26012640 Opc = Pattern == MachineCombinerPattern::MC_MULSUBW_OP2 ? AArch64::MSUBWrrr
26022641 : AArch64::MSUBXrrr;
2603 MUL = genMadd(MF, MRI, TII, Root, InsInstrs, 2, Opc);
2642 if (Pattern == MachineCombinerPattern::MC_MULSUBW_OP2)
2643 RC = &AArch64::GPR32RegClass;
2644 else
2645 RC = &AArch64::GPR64RegClass;
2646 MUL = genMadd(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC);
26042647 break;
26052648 case MachineCombinerPattern::MC_MULSUBWI_OP1:
26062649 case MachineCombinerPattern::MC_MULSUBXI_OP1: {
26092652 // ==> ORR V, ZR, -Imm
26102653 // ==> MADD R,A,B,V // = -Imm + A*B
26112654 // --- Create(MADD);
2612 const TargetRegisterClass *RC =
2613 MRI.getRegClass(Root.getOperand(1).getReg());
2614 unsigned NewVR = MRI.createVirtualRegister(RC);
2655 const TargetRegisterClass *OrrRC = nullptr;
26152656 unsigned BitSize, OrrOpc, ZeroReg;
26162657 if (Pattern == MachineCombinerPattern::MC_MULSUBWI_OP1) {
2658 OrrOpc = AArch64::ORRWri;
2659 RC = &AArch64::GPR32spRegClass;
26172660 BitSize = 32;
2618 OrrOpc = AArch64::ORRWri;
26192661 ZeroReg = AArch64::WZR;
26202662 Opc = AArch64::MADDWrrr;
2663 RC = &AArch64::GPR32RegClass;
26212664 } else {
26222665 OrrOpc = AArch64::ORRXri;
2666 RC = &AArch64::GPR64RegClass;
26232667 BitSize = 64;
26242668 ZeroReg = AArch64::XZR;
26252669 Opc = AArch64::MADDXrrr;
2626 }
2670 RC = &AArch64::GPR64RegClass;
2671 }
2672 unsigned NewVR = MRI.createVirtualRegister(OrrRC);
26272673 int Imm = Root.getOperand(2).getImm();
26282674 if (Root.getOperand(3).isImm()) {
2629 unsigned val = Root.getOperand(3).getImm();
2630 Imm = Imm << val;
2675 unsigned Val = Root.getOperand(3).getImm();
2676 Imm = Imm << Val;
26312677 }
26322678 uint64_t UImm = -Imm << (64 - BitSize) >> (64 - BitSize);
26332679 uint64_t Encoding;
26342680 if (AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding)) {
26352681 MachineInstrBuilder MIB1 =
2636 BuildMI(MF, Root.getDebugLoc(), TII->get(OrrOpc))
2637 .addOperand(MachineOperand::CreateReg(NewVR, true))
2682 BuildMI(MF, Root.getDebugLoc(), TII->get(OrrOpc), NewVR)
26382683 .addReg(ZeroReg)
26392684 .addImm(Encoding);
26402685 InsInstrs.push_back(MIB1);
26412686 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0));
2642 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR);
2643 }
2644 } break;
2645 }
2687 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC);
2688 }
2689 break;
2690 }
2691 } // end switch (Pattern)
26462692 // Record MUL and ADD/SUB for deletion
26472693 DelInstrs.push_back(MUL);
26482694 DelInstrs.push_back(&Root);
0 ; RUN: llc -mtriple=aarch64-apple-darwin -verify-machineinstrs < %s | FileCheck %s
1
2 ; Test that we use the correct register class.
3 define i32 @mul_add_imm(i32 %a, i32 %b) {
4 ; CHECK-LABEL: mul_add_imm
5 ; CHECK: orr [[REG:w[0-9]+]], wzr, #0x4
6 ; CHECK-NEXT: madd {{w[0-9]+}}, w0, w1, [[REG]]
7 %1 = mul i32 %a, %b
8 %2 = add i32 %1, 4
9 ret i32 %2
10 }
11
12 define i32 @mul_sub_imm1(i32 %a, i32 %b) {
13 ; CHECK-LABEL: mul_sub_imm1
14 ; CHECK: orr [[REG:w[0-9]+]], wzr, #0x4
15 ; CHECK-NEXT: msub {{w[0-9]+}}, w0, w1, [[REG]]
16 %1 = mul i32 %a, %b
17 %2 = sub i32 4, %1
18 ret i32 %2
19 }