Index: lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -597,22 +597,58 @@ MI.eraseFromParent(); return Legalized; } + case TargetOpcode::G_FCMP: { + unsigned Op0Ext, Op1Ext, DstReg; + unsigned Cmp1 = MI.getOperand(2).getReg(); + unsigned Cmp2 = MI.getOperand(3).getReg(); + if (TypeIdx == 0) { + Op0Ext = Cmp1; + Op1Ext = Cmp2; + DstReg = MRI.createGenericVirtualRegister(WideTy); + } else { + Op0Ext = MRI.createGenericVirtualRegister(WideTy); + Op1Ext = MRI.createGenericVirtualRegister(WideTy); + DstReg = MI.getOperand(0).getReg(); + MIRBuilder.buildInstr(TargetOpcode::G_FPEXT, Op0Ext, Cmp1); + MIRBuilder.buildInstr(TargetOpcode::G_FPEXT, Op1Ext, Cmp2); + } + MIRBuilder.buildFCmp( + static_cast(MI.getOperand(1).getPredicate()), + DstReg, Op0Ext, Op1Ext); + if (TypeIdx == 0) + MIRBuilder.buildInstr(TargetOpcode::G_TRUNC, MI.getOperand(0).getReg(), + DstReg); + MI.eraseFromParent(); + return Legalized; + } case TargetOpcode::G_ICMP: { - assert(TypeIdx == 1 && "unable to legalize predicate"); bool IsSigned = CmpInst::isSigned( static_cast(MI.getOperand(1).getPredicate())); - unsigned Op0Ext = MRI.createGenericVirtualRegister(WideTy); - unsigned Op1Ext = MRI.createGenericVirtualRegister(WideTy); - if (IsSigned) { - MIRBuilder.buildSExt(Op0Ext, MI.getOperand(2).getReg()); - MIRBuilder.buildSExt(Op1Ext, MI.getOperand(3).getReg()); + unsigned Cmp1 = MI.getOperand(2).getReg(); + unsigned Cmp2 = MI.getOperand(3).getReg(); + unsigned Op0Ext, Op1Ext, DstReg; + if (TypeIdx == 0) { + Op0Ext = Cmp1; + Op1Ext = Cmp2; + DstReg = MRI.createGenericVirtualRegister(WideTy); } else { - MIRBuilder.buildZExt(Op0Ext, MI.getOperand(2).getReg()); - MIRBuilder.buildZExt(Op1Ext, MI.getOperand(3).getReg()); + Op0Ext = MRI.createGenericVirtualRegister(WideTy); + Op1Ext = MRI.createGenericVirtualRegister(WideTy); + DstReg = MI.getOperand(0).getReg(); + if (IsSigned) { + MIRBuilder.buildSExt(Op0Ext, Cmp1); + MIRBuilder.buildSExt(Op1Ext, Cmp2); + } else { + MIRBuilder.buildZExt(Op0Ext, Cmp1); + MIRBuilder.buildZExt(Op1Ext, Cmp2); + } } MIRBuilder.buildICmp( static_cast(MI.getOperand(1).getPredicate()), - MI.getOperand(0).getReg(), Op0Ext, Op1Ext); + DstReg, Op0Ext, Op1Ext); + if (TypeIdx == 0) + MIRBuilder.buildInstr(TargetOpcode::G_TRUNC, MI.getOperand(0).getReg(), + DstReg); MI.eraseFromParent(); return Legalized; } Index: lib/Target/AArch64/AArch64InstructionSelector.cpp =================================================================== --- lib/Target/AArch64/AArch64InstructionSelector.cpp +++ lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -513,6 +513,8 @@ const unsigned CondReg = I.getOperand(0).getReg(); MachineBasicBlock *DestMBB = I.getOperand(1).getMBB(); MachineInstr *CCMI = MRI.getVRegDef(CondReg); + if (CCMI->getOpcode() == TargetOpcode::G_TRUNC) + CCMI = MRI.getVRegDef(CCMI->getOperand(1).getReg()); if (CCMI->getOpcode() != TargetOpcode::G_ICMP) return false; @@ -1261,9 +1263,9 @@ return true; } case TargetOpcode::G_ICMP: { - if (Ty != LLT::scalar(1)) { + if (Ty != LLT::scalar(32)) { DEBUG(dbgs() << "G_ICMP result has type: " << Ty - << ", expected: " << LLT::scalar(1) << '\n'); + << ", expected: " << LLT::scalar(32) << '\n'); return false; } @@ -1308,9 +1310,9 @@ } case TargetOpcode::G_FCMP: { - if (Ty != LLT::scalar(1)) { + if (Ty != LLT::scalar(32)) { DEBUG(dbgs() << "G_FCMP result has type: " << Ty - << ", expected: " << LLT::scalar(1) << '\n'); + << ", expected: " << LLT::scalar(32) << '\n'); return false; } Index: lib/Target/AArch64/AArch64LegalizerInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -131,16 +131,18 @@ setAction({TargetOpcode::G_FCONSTANT, s16}, WidenScalar); - setAction({G_ICMP, s1}, Legal); setAction({G_ICMP, 1, s32}, Legal); setAction({G_ICMP, 1, s64}, Legal); setAction({G_ICMP, 1, p0}, Legal); for (auto Ty : {s1, s8, s16}) { + setAction({G_ICMP, Ty}, WidenScalar); + setAction({G_FCMP, Ty}, WidenScalar); setAction({G_ICMP, 1, Ty}, WidenScalar); } - setAction({G_FCMP, s1}, Legal); + setAction({G_ICMP, s32}, Legal); + setAction({G_FCMP, s32}, Legal); setAction({G_FCMP, 1, s32}, Legal); setAction({G_FCMP, 1, s64}, Legal); Index: test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir =================================================================== --- test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir +++ test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir @@ -32,12 +32,14 @@ %2(s8) = G_TRUNC %0 %3(s8) = G_TRUNC %1 - ; CHECK: %4(s1) = G_ICMP intpred(sge), %0(s64), %1 + ; CHECK: [[CMP1:%[0-9]+]](s32) = G_ICMP intpred(sge), %0(s64), %1 + ; CHECK: [[CMP_T1:%[0-9]+]](s1) = G_TRUNC [[CMP1]] %4(s1) = G_ICMP intpred(sge), %0, %1 ; CHECK: [[LHS32:%[0-9]+]](s32) = G_ZEXT %2 ; CHECK: [[RHS32:%[0-9]+]](s32) = G_ZEXT %3 - ; CHECK: %8(s1) = G_ICMP intpred(ult), [[LHS32]](s32), [[RHS32]] + ; CHECK: [[CMP2:%[0-9]+]](s32) = G_ICMP intpred(ult), [[LHS32]](s32), [[RHS32]] + ; CHECK: [[CMP_T2:%[0-9]+]](s1) = G_TRUNC [[CMP2]] %8(s1) = G_ICMP intpred(ult), %2, %3 %9(p0) = G_INTTOPTR %0(s64) Index: test/CodeGen/AArch64/GlobalISel/legalize-fcmp.mir =================================================================== --- test/CodeGen/AArch64/GlobalISel/legalize-fcmp.mir +++ test/CodeGen/AArch64/GlobalISel/legalize-fcmp.mir @@ -18,6 +18,8 @@ - { id: 3, class: _ } - { id: 4, class: _ } - { id: 5, class: _ } + - { id: 6, class: _ } + - { id: 7, class: _ } body: | bb.0.entry: liveins: %x0, %x1, %x2, %x3 @@ -27,9 +29,13 @@ %2(s32) = G_TRUNC %0 %3(s32) = G_TRUNC %1 - ; CHECK: %4(s1) = G_FCMP floatpred(oge), %0(s64), %1 - %4(s1) = G_FCMP floatpred(oge), %0, %1 + ; CHECK: [[CMP1:%[0-9]+]](s32) = G_FCMP floatpred(oge), %0(s64), %1 + ; CHECK: [[TRUNC1:%[0-9]+]](s1) = G_TRUNC [[CMP1]] + %4(s32) = G_FCMP floatpred(oge), %0, %1 + %6(s1) = G_TRUNC %4(s32) - ; CHECK: %5(s1) = G_FCMP floatpred(uno), %2(s32), %3 - %5(s1) = G_FCMP floatpred(uno), %2, %3 + ; CHECK: [[CMP2:%[0-9]+]](s32) = G_FCMP floatpred(uno), %2(s32), %3 + ; CHECK: [[TRUNC2:%[0-9]+]](s1) = G_TRUNC [[CMP2]] + %5(s32) = G_FCMP floatpred(uno), %2, %3 + %7(s1) = G_TRUNC %5(s32) ... Index: test/CodeGen/AArch64/GlobalISel/legalize-mul.mir =================================================================== --- test/CodeGen/AArch64/GlobalISel/legalize-mul.mir +++ test/CodeGen/AArch64/GlobalISel/legalize-mul.mir @@ -51,7 +51,8 @@ ; CHECK: %2(s64) = G_MUL %0, %1 ; CHECK: [[HI:%[0-9]+]](s64) = G_SMULH %0, %1 ; CHECK: [[ZERO:%[0-9]+]](s64) = G_CONSTANT i64 0 - ; CHECK: %3(s1) = G_ICMP intpred(ne), [[HI]](s64), [[ZERO]] + ; CHECK: [[CMP:%[0-9]+]](s32) = G_ICMP intpred(ne), [[HI]](s64), [[ZERO]] + ; CHECK: [[TRUNC:%[0-9]+]](s1) = G_TRUNC [[CMP]] %2:_(s64), %3:_(s1) = G_SMULO %0, %1 ... Index: test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir =================================================================== --- test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir +++ test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir @@ -524,13 +524,16 @@ registers: - { id: 0, class: _ } - { id: 1, class: _ } + - { id: 2, class: _ } body: | bb.0: liveins: %w0 ; CHECK: %0(s32) = COPY %w0 - ; CHECK: %1(s1) = G_ICMP intpred(ne), %0(s32), %0 + ; CHECK: %1(s32) = G_ICMP intpred(ne), %0(s32), %0 + ; CHECK: %2(s1) = G_TRUNC %1(s32) %0(s32) = COPY %w0 - %1(s1) = G_ICMP intpred(ne), %0, %0 + %1(s32) = G_ICMP intpred(ne), %0, %0 + %2(s1) = G_TRUNC %1(s32) ... --- @@ -543,13 +546,16 @@ registers: - { id: 0, class: _ } - { id: 1, class: _ } + - { id: 2, class: _ } body: | bb.0: liveins: %x0 ; CHECK: %0(p0) = COPY %x0 - ; CHECK: %1(s1) = G_ICMP intpred(ne), %0(p0), %0 + ; CHECK: %1(s32) = G_ICMP intpred(ne), %0(p0), %0 + ; CHECK: %2(s1) = G_TRUNC %1(s32) %0(p0) = COPY %x0 - %1(s1) = G_ICMP intpred(ne), %0, %0 + %1(s32) = G_ICMP intpred(ne), %0, %0 + %2(s1) = G_TRUNC %1(s32) ... --- @@ -784,13 +790,16 @@ registers: - { id: 0, class: _ } - { id: 1, class: _ } + - { id: 2, class: _ } body: | bb.0: liveins: %s0 ; CHECK: %0(s32) = COPY %s0 - ; CHECK: %1(s1) = G_FCMP floatpred(olt), %0(s32), %0 + ; CHECK: [[FCMP:%[0-9]+]](s32) = G_FCMP floatpred(olt), %0(s32), %0 + ; CHECK: [[TRUNC:%[0-9]+]](s1) = G_TRUNC [[FCMP]] %0(s32) = COPY %s0 - %1(s1) = G_FCMP floatpred(olt), %0, %0 + %1(s32) = G_FCMP floatpred(olt), %0, %0 + %2(s1) = G_TRUNC %1(s32) ... --- Index: test/CodeGen/AArch64/GlobalISel/select-cbz.mir =================================================================== --- test/CodeGen/AArch64/GlobalISel/select-cbz.mir +++ test/CodeGen/AArch64/GlobalISel/select-cbz.mir @@ -25,8 +25,9 @@ %0:gpr(s32) = COPY %w0 %1:gpr(s32) = G_CONSTANT i32 0 - %2:gpr(s1) = G_ICMP intpred(eq), %0, %1 - G_BRCOND %2(s1), %bb.1 + %2:gpr(s32) = G_ICMP intpred(eq), %0, %1 + %3:gpr(s1) = G_TRUNC %2(s32) + G_BRCOND %3(s1), %bb.1 G_BR %bb.0 bb.1: @@ -50,8 +51,9 @@ %0:gpr(s64) = COPY %x0 %1:gpr(s64) = G_CONSTANT i64 0 - %2:gpr(s1) = G_ICMP intpred(eq), %0, %1 - G_BRCOND %2(s1), %bb.1 + %2:gpr(s32) = G_ICMP intpred(eq), %0, %1 + %3:gpr(s1) = G_TRUNC %2(s32) + G_BRCOND %3(s1), %bb.1 G_BR %bb.0 bb.1: @@ -75,8 +77,9 @@ %0:gpr(s32) = COPY %w0 %1:gpr(s32) = G_CONSTANT i32 0 - %2:gpr(s1) = G_ICMP intpred(ne), %0, %1 - G_BRCOND %2(s1), %bb.1 + %2:gpr(s32) = G_ICMP intpred(ne), %0, %1 + %3:gpr(s1) = G_TRUNC %2(s32) + G_BRCOND %3(s1), %bb.1 G_BR %bb.0 bb.1: @@ -100,8 +103,9 @@ %0:gpr(s64) = COPY %x0 %1:gpr(s64) = G_CONSTANT i64 0 - %2:gpr(s1) = G_ICMP intpred(ne), %0, %1 - G_BRCOND %2(s1), %bb.1 + %2:gpr(s32) = G_ICMP intpred(ne), %0, %1 + %3:gpr(s1) = G_TRUNC %2(s32) + G_BRCOND %3(s1), %bb.1 G_BR %bb.0 bb.1: Index: test/CodeGen/AArch64/GlobalISel/select.mir =================================================================== --- test/CodeGen/AArch64/GlobalISel/select.mir +++ test/CodeGen/AArch64/GlobalISel/select.mir @@ -145,6 +145,9 @@ - { id: 3, class: gpr } - { id: 4, class: gpr } - { id: 5, class: gpr } + - { id: 6, class: gpr } + - { id: 7, class: gpr } + - { id: 8, class: gpr } # CHECK: body: # CHECK: %wzr = SUBSWrr %0, %0, implicit-def %nzcv @@ -161,16 +164,19 @@ liveins: %w0, %x0 %0(s32) = COPY %w0 - %1(s1) = G_ICMP intpred(eq), %0, %0 - %w0 = COPY %1(s1) + %1(s32) = G_ICMP intpred(eq), %0, %0 + %6(s1) = G_TRUNC %1(s32) + %w0 = COPY %6(s1) %2(s64) = COPY %x0 - %3(s1) = G_ICMP intpred(uge), %2, %2 - %w0 = COPY %3(s1) + %3(s32) = G_ICMP intpred(uge), %2, %2 + %7(s1) = G_TRUNC %3(s32) + %w0 = COPY %7(s1) %4(p0) = COPY %x0 - %5(s1) = G_ICMP intpred(ne), %4, %4 - %w0 = COPY %5(s1) + %5(s32) = G_ICMP intpred(ne), %4, %4 + %8(s1) = G_TRUNC %5(s32) + %w0 = COPY %8(s1) ... --- @@ -191,6 +197,8 @@ - { id: 1, class: gpr } - { id: 2, class: fpr } - { id: 3, class: gpr } + - { id: 4, class: gpr } + - { id: 5, class: gpr } # CHECK: body: # CHECK: FCMPSrr %0, %0, implicit-def %nzcv @@ -206,12 +214,14 @@ liveins: %w0, %x0 %0(s32) = COPY %s0 - %1(s1) = G_FCMP floatpred(one), %0, %0 - %w0 = COPY %1(s1) + %1(s32) = G_FCMP floatpred(one), %0, %0 + %4(s1) = G_TRUNC %1(s32) + %w0 = COPY %4(s1) %2(s64) = COPY %d0 - %3(s1) = G_FCMP floatpred(uge), %2, %2 - %w0 = COPY %3(s1) + %3(s32) = G_FCMP floatpred(uge), %2, %2 + %5(s1) = G_TRUNC %3(s32) + %w0 = COPY %5(s1) ...