Index: llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -309,6 +309,9 @@ MachineOperand &RHS, MachineOperand &Predicate, MachineIRBuilder &MIB) const; + MachineInstr *tryOptArithShiftedCompare(MachineOperand &LHS, + MachineOperand &RHS, + MachineIRBuilder &MIB) const; /// Return true if \p MI is a load or store of \p NumBytes bytes. bool isLoadStoreOfNumBytes(const MachineInstr &MI, unsigned NumBytes) const; @@ -3710,6 +3713,12 @@ if (ImmedCmp) return {ImmedCmp, (CmpInst::Predicate)Predicate.getPredicate()}; + // If we don't have an immediate, we may have a shift which can be folded + // into the compare. + MachineInstr *ShiftedCmp = tryOptArithShiftedCompare(LHS, RHS, MIRBuilder); + if (ShiftedCmp) + return {ShiftedCmp, (CmpInst::Predicate)Predicate.getPredicate()}; + auto CmpMI = MIRBuilder.buildInstr(CmpOpc, {ZReg}, {LHS.getReg(), RHS.getReg()}); // Make sure that we can constrain the compare that we emitted. @@ -4142,6 +4151,35 @@ return &*CmpMI; } +MachineInstr *AArch64InstructionSelector::tryOptArithShiftedCompare( + MachineOperand &LHS, MachineOperand &RHS, MachineIRBuilder &MIB) const { + // We are looking for the following pattern: + // + // shift = G_SHL/ASHR/LHSR y, c + // ... + // cmp = G_ICMP pred, something, shift + // + // Since we will select the G_ICMP to a SUBS, we can potentially fold the + // shift into the subtract. + static const unsigned OpcTable[2] = {AArch64::SUBSWrs, AArch64::SUBSXrs}; + static const Register ZRegTable[2] = {AArch64::WZR, AArch64::XZR}; + auto ImmFns = selectShiftedRegister(RHS); + if (!ImmFns) + return nullptr; + MachineRegisterInfo &MRI = *MIB.getMRI(); + auto Ty = MRI.getType(LHS.getReg()); + assert(!Ty.isVector() && "Expected scalar or pointer only?"); + unsigned Size = Ty.getSizeInBits(); + bool Idx = (Size == 64); + Register ZReg = ZRegTable[Idx]; + unsigned Opc = OpcTable[Idx]; + auto CmpMI = MIB.buildInstr(Opc, {ZReg}, {LHS.getReg()}); + for (auto &RenderFn : *ImmFns) + RenderFn(CmpMI); + constrainSelectedInstRegOperands(*CmpMI, TII, TRI, RBI); + return &*CmpMI; +} + bool AArch64InstructionSelector::tryOptVectorDup(MachineInstr &I) const { // Try to match a vector splat operation into a dup instruction. // We're looking for this pattern: Index: llvm/test/CodeGen/AArch64/GlobalISel/opt-shifted-reg-compare.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/GlobalISel/opt-shifted-reg-compare.mir @@ -0,0 +1,775 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple aarch64-unknown-unknown -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s +# +# Verify that we can fold shifts into G_ICMP variants. +# +# Because these are selected as a SUBS, we can fold a shift into the addressing +# mode in the same way. +# +# We should not have shifts in any of the compares below. These should be +# folded into the SUBSWrs instruction. + +... +--- +name: eq_shl +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: eq_shl + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 3, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_SHL %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(eq), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 + +... +--- +name: eq_ashr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: eq_ashr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 131, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_ASHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(eq), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 + +... +--- +name: eq_lshr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: eq_lshr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 67, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_LSHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(eq), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 + +... +--- +name: ne_shl +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ne_shl + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 3, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 0, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_SHL %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ne), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 + +... +--- +name: ne_ashr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ne_ashr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 131, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 0, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_ASHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ne), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 + +... +--- +name: ne_lshr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ne_lshr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 67, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 0, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_LSHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ne), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 + +... +--- +name: ult_shl +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ult_shl + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 3, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 2, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_SHL %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ult), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: ult_ashr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ult_ashr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 131, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 2, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_ASHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ult), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: ult_lshr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ult_lshr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 67, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 2, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_LSHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ult), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: ugt_shl +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ugt_shl + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 3, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 9, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_SHL %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ugt), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: ugt_ashr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ugt_ashr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 131, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 9, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_ASHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ugt), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: ugt_lshr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ugt_lshr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 67, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 9, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_LSHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ugt), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... + +... +--- +name: uge_shl +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: uge_shl + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 3, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 3, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_SHL %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(uge), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: uge_ashr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: uge_ashr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 131, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 3, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_ASHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(uge), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: uge_lshr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: uge_lshr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 67, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 3, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_LSHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(uge), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... + +... +--- +name: ule_shl +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ule_shl + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 3, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 8, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_SHL %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ule), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: ule_ashr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ule_ashr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 131, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 8, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_ASHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ule), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: ule_lshr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: ule_lshr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 67, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 8, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_LSHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(ule), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +... +--- +name: slt_shl +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: slt_shl + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 3, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_SHL %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(slt), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: slt_ashr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: slt_ashr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 131, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_ASHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(slt), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: slt_lshr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: slt_lshr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 67, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_LSHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(slt), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: sgt_shl +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: sgt_shl + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 3, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_SHL %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(sgt), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: sgt_ashr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: sgt_ashr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 131, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_ASHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(sgt), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: sgt_lshr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: sgt_lshr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 67, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_LSHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(sgt), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: sge_shl +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: sge_shl + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 3, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_SHL %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(sge), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: sge_ashr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: sge_ashr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 131, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_ASHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(sge), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: sge_lshr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: sge_lshr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 67, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_LSHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(sge), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... + +... +--- +name: sle_shl +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: sle_shl + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 3, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_SHL %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(sle), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: sle_ashr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: sle_ashr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 131, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_ASHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(sle), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +... +--- +name: sle_lshr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: sle_lshr + ; CHECK: liveins: $w0, $w1 + ; CHECK: %copy0:gpr32 = COPY $w0 + ; CHECK: %copy1:gpr32 = COPY $w1 + ; CHECK: $wzr = SUBSWrs %copy1, %copy0, 67, implicit-def $nzcv + ; CHECK: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv + ; CHECK: $w0 = COPY %cmp + ; CHECK: RET_ReallyLR implicit $w0 + %copy0:gpr(s32) = COPY $w0 + %copy1:gpr(s32) = COPY $w1 + %three:gpr(s32) = G_CONSTANT i32 3 + %shift:gpr(s32) = G_LSHR %copy0, %three(s32) + %cmp:gpr(s32) = G_ICMP intpred(sle), %copy1(s32), %shift + $w0 = COPY %cmp(s32) + RET_ReallyLR implicit $w0 +...