llvm.org GIT mirror llvm / dc84a08
Merging r310534: ------------------------------------------------------------------------ r310534 | matze | 2017-08-09 15:22:05 -0700 (Wed, 09 Aug 2017) | 20 lines ARM: Fix CMP_SWAP expansion Clean up after my misguided attempt in r304267 to "fix" CMP_SWAP returning an uninitialized status value. - I was always using tMOVi8 to zero the status register which cannot encode higher register numbers and llvm would silently miscompile) - Nobody was ever looking at that status value outside the expansion. ARMDAGToDAGISel::SelectCMP_SWAP() the only place creating CMP_SWAP instructions was not mapping anything to it. (The cmpxchg status value from llvm IR is lowered to a manual comparison after the CMP_SWAP) So this: - Renames the register from "status" to "temp" it make it obvious that it isn't used outside the expansion. - Remove the zeroing status/temp register. - Keep the live-in list improvements from r304267 Fixes http://llvm.org/PR34056 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@310628 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 3 years ago
3 changed file(s) with 19 addition(s) and 38 deletion(s). Raw diff Collapse all Expand all
768768 MachineInstr &MI = *MBBI;
769769 DebugLoc DL = MI.getDebugLoc();
770770 const MachineOperand &Dest = MI.getOperand(0);
771 unsigned StatusReg = MI.getOperand(1).getReg();
772 bool StatusDead = MI.getOperand(1).isDead();
771 unsigned TempReg = MI.getOperand(1).getReg();
773772 // Duplicating undef operands into 2 instructions does not guarantee the same
774773 // value on both; However undef should be replaced by xzr anyway.
775774 assert(!MI.getOperand(2).isUndef() && "cannot handle undef");
796795 }
797796
798797 // .Lloadcmp:
799 // mov wStatus, #0
800798 // ldrex rDest, [rAddr]
801799 // cmp rDest, rDesired
802800 // bne .Ldone
803 if (!StatusDead) {
804 if (IsThumb) {
805 BuildMI(LoadCmpBB, DL, TII->get(ARM::tMOVi8), StatusReg)
806 .addDef(ARM::CPSR, RegState::Dead)
807 .addImm(0)
808 .add(predOps(ARMCC::AL));
809 } else {
810 BuildMI(LoadCmpBB, DL, TII->get(ARM::MOVi), StatusReg)
811 .addImm(0)
812 .add(predOps(ARMCC::AL))
813 .add(condCodeOp());
814 }
815 }
816801
817802 MachineInstrBuilder MIB;
818803 MIB = BuildMI(LoadCmpBB, DL, TII->get(LdrexOp), Dest.getReg());
835820 LoadCmpBB->addSuccessor(StoreBB);
836821
837822 // .Lstore:
838 // strex rStatus, rNew, [rAddr]
839 // cmp rStatus, #0
823 // strex rTempReg, rNew, [rAddr]
824 // cmp rTempReg, #0
840825 // bne .Lloadcmp
841 MIB = BuildMI(StoreBB, DL, TII->get(StrexOp), StatusReg)
826 MIB = BuildMI(StoreBB, DL, TII->get(StrexOp), TempReg)
842827 .addReg(NewReg)
843828 .addReg(AddrReg);
844829 if (StrexOp == ARM::t2STREX)
847832
848833 unsigned CMPri = IsThumb ? ARM::t2CMPri : ARM::CMPri;
849834 BuildMI(StoreBB, DL, TII->get(CMPri))
850 .addReg(StatusReg, getKillRegState(StatusDead))
835 .addReg(TempReg, RegState::Kill)
851836 .addImm(0)
852837 .add(predOps(ARMCC::AL));
853838 BuildMI(StoreBB, DL, TII->get(Bcc))
903888 MachineInstr &MI = *MBBI;
904889 DebugLoc DL = MI.getDebugLoc();
905890 MachineOperand &Dest = MI.getOperand(0);
906 unsigned StatusReg = MI.getOperand(1).getReg();
907 bool StatusDead = MI.getOperand(1).isDead();
891 unsigned TempReg = MI.getOperand(1).getReg();
908892 // Duplicating undef operands into 2 instructions does not guarantee the same
909893 // value on both; However undef should be replaced by xzr anyway.
910894 assert(!MI.getOperand(2).isUndef() && "cannot handle undef");
930914 // .Lloadcmp:
931915 // ldrexd rDestLo, rDestHi, [rAddr]
932916 // cmp rDestLo, rDesiredLo
933 // sbcs rStatus, rDestHi, rDesiredHi
917 // sbcs rTempReg, rDestHi, rDesiredHi
934918 // bne .Ldone
935919 unsigned LDREXD = IsThumb ? ARM::t2LDREXD : ARM::LDREXD;
936920 MachineInstrBuilder MIB;
958942 LoadCmpBB->addSuccessor(StoreBB);
959943
960944 // .Lstore:
961 // strexd rStatus, rNewLo, rNewHi, [rAddr]
962 // cmp rStatus, #0
945 // strexd rTempReg, rNewLo, rNewHi, [rAddr]
946 // cmp rTempReg, #0
963947 // bne .Lloadcmp
964948 unsigned STREXD = IsThumb ? ARM::t2STREXD : ARM::STREXD;
965 MIB = BuildMI(StoreBB, DL, TII->get(STREXD), StatusReg);
949 MIB = BuildMI(StoreBB, DL, TII->get(STREXD), TempReg);
966950 addExclusiveRegPair(MIB, New, 0, IsThumb, TRI);
967951 MIB.addReg(AddrReg).add(predOps(ARMCC::AL));
968952
969953 unsigned CMPri = IsThumb ? ARM::t2CMPri : ARM::CMPri;
970954 BuildMI(StoreBB, DL, TII->get(CMPri))
971 .addReg(StatusReg, getKillRegState(StatusDead))
955 .addReg(TempReg, RegState::Kill)
972956 .addImm(0)
973957 .add(predOps(ARMCC::AL));
974958 BuildMI(StoreBB, DL, TII->get(Bcc))
60526052 // significantly more naive than the standard expansion: we conservatively
60536053 // assume seq_cst, strong cmpxchg and omit clrex on failure.
60546054
6055 let Constraints = "@earlyclobber $Rd,@earlyclobber $status",
6055 let Constraints = "@earlyclobber $Rd,@earlyclobber $temp",
60566056 mayLoad = 1, mayStore = 1 in {
6057 def CMP_SWAP_8 : PseudoInst<(outs GPR:$Rd, GPR:$status),
6057 def CMP_SWAP_8 : PseudoInst<(outs GPR:$Rd, GPR:$temp),
60586058 (ins GPR:$addr, GPR:$desired, GPR:$new),
60596059 NoItinerary, []>, Sched<[]>;
60606060
6061 def CMP_SWAP_16 : PseudoInst<(outs GPR:$Rd, GPR:$status),
6061 def CMP_SWAP_16 : PseudoInst<(outs GPR:$Rd, GPR:$temp),
60626062 (ins GPR:$addr, GPR:$desired, GPR:$new),
60636063 NoItinerary, []>, Sched<[]>;
60646064
6065 def CMP_SWAP_32 : PseudoInst<(outs GPR:$Rd, GPR:$status),
6065 def CMP_SWAP_32 : PseudoInst<(outs GPR:$Rd, GPR:$temp),
60666066 (ins GPR:$addr, GPR:$desired, GPR:$new),
60676067 NoItinerary, []>, Sched<[]>;
60686068
6069 def CMP_SWAP_64 : PseudoInst<(outs GPRPair:$Rd, GPR:$status),
6069 def CMP_SWAP_64 : PseudoInst<(outs GPRPair:$Rd, GPR:$temp),
60706070 (ins GPR:$addr, GPRPair:$desired, GPRPair:$new),
60716071 NoItinerary, []>, Sched<[]>;
60726072 }
99 ; CHECK: dmb ish
1010 ; CHECK: uxtb [[DESIRED:r[0-9]+]], [[DESIRED]]
1111 ; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
12 ; CHECK: mov{{s?}} [[STATUS:r[0-9]+]], #0
1312 ; CHECK: ldrexb [[OLD:r[0-9]+]], [r0]
1413 ; CHECK: cmp [[OLD]], [[DESIRED]]
1514 ; CHECK: bne [[DONE:.LBB[0-9]+_[0-9]+]]
16 ; CHECK: strexb [[STATUS]], r2, [r0]
15 ; CHECK: strexb [[STATUS:r[0-9]+]], r2, [r0]
1716 ; CHECK: cmp{{(\.w)?}} [[STATUS]], #0
1817 ; CHECK: bne [[RETRY]]
1918 ; CHECK: [[DONE]]:
2928 ; CHECK: dmb ish
3029 ; CHECK: uxth [[DESIRED:r[0-9]+]], [[DESIRED]]
3130 ; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
32 ; CHECK: mov{{s?}} [[STATUS:r[0-9]+]], #0
3331 ; CHECK: ldrexh [[OLD:r[0-9]+]], [r0]
3432 ; CHECK: cmp [[OLD]], [[DESIRED]]
3533 ; CHECK: bne [[DONE:.LBB[0-9]+_[0-9]+]]
36 ; CHECK: strexh [[STATUS]], r2, [r0]
34 ; CHECK: strexh [[STATUS:r[0-9]+]], r2, [r0]
3735 ; CHECK: cmp{{(\.w)?}} [[STATUS]], #0
3836 ; CHECK: bne [[RETRY]]
3937 ; CHECK: [[DONE]]:
4947 ; CHECK: dmb ish
5048 ; CHECK-NOT: uxt
5149 ; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
52 ; CHECK: mov{{s?}} [[STATUS:r[0-9]+]], #0
5350 ; CHECK: ldrex [[OLD:r[0-9]+]], [r0]
5451 ; CHECK: cmp [[OLD]], [[DESIRED]]
5552 ; CHECK: bne [[DONE:.LBB[0-9]+_[0-9]+]]
56 ; CHECK: strex [[STATUS]], r2, [r0]
53 ; CHECK: strex [[STATUS:r[0-9]+]], r2, [r0]
5754 ; CHECK: cmp{{(\.w)?}} [[STATUS]], #0
5855 ; CHECK: bne [[RETRY]]
5956 ; CHECK: [[DONE]]: