Index: llvm/trunk/lib/CodeGen/GlobalISel/Utils.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GlobalISel/Utils.cpp +++ llvm/trunk/lib/CodeGen/GlobalISel/Utils.cpp @@ -238,6 +238,9 @@ if (TargetRegisterInfo::isPhysicalRegister(VReg)) return None; break; + case TargetOpcode::G_INTTOPTR: + VReg = MI->getOperand(1).getReg(); + break; default: return None; } Index: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -899,12 +899,23 @@ Register LHS = CCMI->getOperand(2).getReg(); Register RHS = CCMI->getOperand(3).getReg(); - if (!getConstantVRegVal(RHS, MRI)) + auto VRegAndVal = getConstantVRegValWithLookThrough(RHS, MRI); + if (!VRegAndVal) std::swap(RHS, LHS); - const auto RHSImm = getConstantVRegVal(RHS, MRI); - if (!RHSImm || *RHSImm != 0) - return false; + VRegAndVal = getConstantVRegValWithLookThrough(RHS, MRI); + if (!VRegAndVal || VRegAndVal->Value != 0) { + MachineIRBuilder MIB(I); + // If we can't select a CBZ then emit a cmp + Bcc. + if (!emitIntegerCompare(CCMI->getOperand(2), CCMI->getOperand(3), + CCMI->getOperand(1), MIB)) + return false; + const AArch64CC::CondCode CC = changeICMPPredToAArch64CC( + (CmpInst::Predicate)CCMI->getOperand(1).getPredicate()); + MIB.buildInstr(AArch64::Bcc, {}, {}).addImm(CC).addMBB(DestMBB); + I.eraseFromParent(); + return true; + } const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI); if (RB.getID() != AArch64::GPRRegBankID) Index: llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-cbz.mir =================================================================== --- llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-cbz.mir +++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-cbz.mir @@ -1,3 +1,4 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py # RUN: llc -mtriple=aarch64-- -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --- | @@ -5,20 +6,23 @@ define void @cbz_s64() { ret void } define void @cbnz_s32() { ret void } define void @cbnz_s64() { ret void } + define hidden void @test_rhs_inttoptr(i64* %p) { ret void } + define hidden void @test_rhs_unknown(i64* %p) { ret void } ... --- -# CHECK-LABEL: name: cbz_s32 name: cbz_s32 legalized: true regBankSelected: true -# CHECK: body: -# CHECK: bb.0: -# CHECK: %0:gpr32 = COPY $w0 -# CHECK: CBZW %0, %bb.1 -# CHECK: B %bb.0 body: | + ; CHECK-LABEL: name: cbz_s32 + ; CHECK: bb.0: + ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000) + ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 + ; CHECK: CBZW [[COPY]], %bb.1 + ; CHECK: B %bb.0 + ; CHECK: bb.1: bb.0: liveins: $w0 successors: %bb.0, %bb.1 @@ -34,17 +38,18 @@ ... --- -# CHECK-LABEL: name: cbz_s64 name: cbz_s64 legalized: true regBankSelected: true -# CHECK: body: -# CHECK: bb.0: -# CHECK: %0:gpr64 = COPY $x0 -# CHECK: CBZX %0, %bb.1 -# CHECK: B %bb.0 body: | + ; CHECK-LABEL: name: cbz_s64 + ; CHECK: bb.0: + ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000) + ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK: CBZX [[COPY]], %bb.1 + ; CHECK: B %bb.0 + ; CHECK: bb.1: bb.0: liveins: $x0 successors: %bb.0, %bb.1 @@ -60,17 +65,18 @@ ... --- -# CHECK-LABEL: name: cbnz_s32 name: cbnz_s32 legalized: true regBankSelected: true -# CHECK: body: -# CHECK: bb.0: -# CHECK: %0:gpr32 = COPY $w0 -# CHECK: CBNZW %0, %bb.1 -# CHECK: B %bb.0 body: | + ; CHECK-LABEL: name: cbnz_s32 + ; CHECK: bb.0: + ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000) + ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 + ; CHECK: CBNZW [[COPY]], %bb.1 + ; CHECK: B %bb.0 + ; CHECK: bb.1: bb.0: liveins: $w0 successors: %bb.0, %bb.1 @@ -86,17 +92,18 @@ ... --- -# CHECK-LABEL: name: cbnz_s64 name: cbnz_s64 legalized: true regBankSelected: true -# CHECK: body: -# CHECK: bb.0: -# CHECK: %0:gpr64 = COPY $x0 -# CHECK: CBNZX %0, %bb.1 -# CHECK: B %bb.0 body: | + ; CHECK-LABEL: name: cbnz_s64 + ; CHECK: bb.0: + ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000) + ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK: CBNZX [[COPY]], %bb.1 + ; CHECK: B %bb.0 + ; CHECK: bb.1: bb.0: liveins: $x0 successors: %bb.0, %bb.1 @@ -110,3 +117,80 @@ bb.1: ... +--- +name: test_rhs_inttoptr +alignment: 2 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: test_rhs_inttoptr + ; CHECK: bb.0: + ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) + ; CHECK: liveins: $x0 + ; CHECK: [[COPY:%[0-9]+]]:gpr64common = COPY $x0 + ; CHECK: CBZX [[COPY]], %bb.2 + ; CHECK: bb.1: + ; CHECK: successors: %bb.2(0x80000000) + ; CHECK: STRXui $xzr, [[COPY]], 0 :: (store 8 into %ir.p) + ; CHECK: bb.2: + ; CHECK: RET_ReallyLR + bb.1: + successors: %bb.2, %bb.3 + liveins: $x0 + + %0:gpr(p0) = COPY $x0 + %2:gpr(s64) = G_CONSTANT i64 0 + %1:gpr(p0) = G_INTTOPTR %2(s64) + %4:gpr(s32) = G_ICMP intpred(eq), %0(p0), %1 + %3:gpr(s1) = G_TRUNC %4(s32) + G_BRCOND %3(s1), %bb.3 + + bb.2: + %5:gpr(s64) = G_CONSTANT i64 0 + G_STORE %5(s64), %0(p0) :: (store 8 into %ir.p) + + bb.3: + RET_ReallyLR + +... +--- +name: test_rhs_unknown +alignment: 2 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: test_rhs_unknown + ; CHECK: bb.0: + ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) + ; CHECK: liveins: $x0 + ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 + ; CHECK: [[LDRXui:%[0-9]+]]:gpr64common = LDRXui [[COPY]], 0 :: (load 8 from %ir.p) + ; CHECK: $xzr = SUBSXri [[LDRXui]], 42, 0, implicit-def $nzcv + ; CHECK: Bcc 0, %bb.2, implicit $nzcv + ; CHECK: bb.1: + ; CHECK: successors: %bb.2(0x80000000) + ; CHECK: STRXui $xzr, [[COPY]], 0 :: (store 8 into %ir.p) + ; CHECK: bb.2: + ; CHECK: RET_ReallyLR + bb.1: + successors: %bb.2, %bb.3 + liveins: $x0 + + %0:gpr(p0) = COPY $x0 + %2:gpr(s64) = G_CONSTANT i64 42 + %4:gpr(s64) = G_CONSTANT i64 0 + %1:gpr(s64) = G_LOAD %0(p0) :: (load 8 from %ir.p) + %5:gpr(s32) = G_ICMP intpred(eq), %1(s64), %2 + %3:gpr(s1) = G_TRUNC %5(s32) + G_BRCOND %3(s1), %bb.3 + + bb.2: + %6:gpr(s64) = G_CONSTANT i64 0 + G_STORE %6(s64), %0(p0) :: (store 8 into %ir.p) + + bb.3: + RET_ReallyLR + +... Index: llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir =================================================================== --- llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir +++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir @@ -62,8 +62,7 @@ ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[SUBSWri]], %subreg.sub_32 ; CHECK: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[SUBREG_TO_REG]], 0, 31 ; CHECK: $xzr = SUBSXri [[UBFMXri]], 71, 0, implicit-def $nzcv - ; CHECK: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 9, implicit $nzcv - ; CHECK: TBNZW [[CSINCWr]], 0, %bb.4 + ; CHECK: Bcc 8, %bb.4, implicit $nzcv ; CHECK: bb.1.entry: ; CHECK: successors: %bb.3(0x2aaaaaab), %bb.4(0x2aaaaaab), %bb.2(0x2aaaaaab) ; CHECK: [[MOVi32imm1:%[0-9]+]]:gpr32 = MOVi32imm 0 Index: llvm/trunk/test/CodeGen/AArch64/GlobalISel/swifterror.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/GlobalISel/swifterror.ll +++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/swifterror.ll @@ -28,12 +28,9 @@ define float @caller(i8* %error_ref) { ; CHECK-LABEL: caller: ; CHECK: mov [[ID:x[0-9]+]], x0 -; CHECK: mov [[ZERO:x[0-9]+]], #0 -; CHECK: mov x21, #0 ; CHECK: bl {{.*}}foo ; CHECK: mov x0, x21 -; CHECK: cmp x21, [[ZERO]] -; CHECK: b.ne +; CHECK: cbnz x21 ; Access part of the error object and save it to error_ref ; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8] ; CHECK: strb [[CODE]], [{{.*}}[[ID]]] @@ -61,12 +58,10 @@ define float @caller2(i8* %error_ref) { ; CHECK-LABEL: caller2: ; CHECK: mov [[ID:x[0-9]+]], x0 -; CHECK: mov [[ZERO:x[0-9]+]], #0 ; CHECK: fmov [[CMP:s[0-9]+]], #1.0 ; CHECK: mov x21, #0 ; CHECK: bl {{.*}}foo -; CHECK: cmp x21, [[ZERO]] -; CHECK: b.ne +; CHECK: cbnz x21 ; CHECK: fcmp s0, [[CMP]] ; CHECK: b.le ; Access part of the error object and save it to error_ref @@ -193,11 +188,9 @@ ; CHECK-LABEL: caller3: ; CHECK: mov [[ID:x[0-9]+]], x0 ; CHECK: mov [[ZERO:x[0-9]+]], #0 -; CHECK: mov x21, #0 ; CHECK: bl {{.*}}foo_sret ; CHECK: mov x0, x21 -; CHECK: cmp x21, [[ZERO]] -; CHECK: b.ne +; CHECK: cbnz x21 ; Access part of the error object and save it to error_ref ; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8] ; CHECK: strb [[CODE]], [{{.*}}[[ID]]] @@ -272,15 +265,13 @@ ; CHECK-LABEL: caller4: ; CHECK: mov [[ID:x[0-9]+]], x0 -; CHECK: mov [[ZERO:x[0-9]+]], #0 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp] ; CHECK: mov x21, #0 ; CHECK: str {{x[0-9]+}}, [sp, #16] ; CHECK: bl {{.*}}foo_vararg ; CHECK: mov x0, x21 -; CHECK: cmp x21, [[ZERO]] -; CHECK: b.ne +; CHECK: cbnz x21 ; Access part of the error object and save it to error_ref ; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8] ; CHECK: strb [[CODE]], [{{.*}}[[ID]]]