Index: lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp +++ lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp @@ -826,6 +826,69 @@ MI.eraseFromParent(); return; } + case AMDGPU::G_SEXT: + case AMDGPU::G_ZEXT: { + unsigned SrcReg = MI.getOperand(1).getReg(); + LLT SrcTy = MRI.getType(SrcReg); + if (SrcTy != LLT::scalar(1)) + return; + + MachineIRBuilder B(MI); + bool Signed = Opc == AMDGPU::G_SEXT; + unsigned DstReg = MI.getOperand(0).getReg(); + LLT DstTy = MRI.getType(DstReg); + const RegisterBank *SrcBank = getRegBank(SrcReg, MRI, *TRI); + if (SrcBank->getID() == AMDGPU::SCCRegBankID || + SrcBank->getID() == AMDGPU::VCCRegBankID) { + const RegisterBank *DstBank = getRegBank(DstReg, MRI, *TRI); + unsigned DstSize = DstTy.getSizeInBits(); + + // 64-bit select is SGPR only + const bool UseSel64 = DstSize > 32 && + SrcBank->getID() == AMDGPU::SCCRegBankID; + + // TODO: Should s16 select be legal? + LLT SelType = UseSel64 ? LLT::scalar(64) : LLT::scalar(32); + auto True = B.buildConstant(SelType, Signed ? -1 : 1); + auto False = B.buildConstant(SelType, 0); + + MRI.setRegBank(True.getReg(0), *DstBank); + MRI.setRegBank(False.getReg(0), *DstBank); + if (DstSize > 32 && SrcBank->getID() != AMDGPU::SCCRegBankID) { + auto Sel = B.buildSelect(SelType, SrcReg, True, False); + MRI.setRegBank(Sel.getReg(0), *DstBank); + B.buildMerge(DstReg, { Sel.getReg(0), Sel.getReg(0) }); + } else if (DstSize < 32) { + auto Sel = B.buildSelect(SelType, SrcReg, True, False); + MRI.setRegBank(Sel.getReg(0), *DstBank); + B.buildTrunc(DstReg, Sel); + } else { + B.buildSelect(DstReg, SrcReg, True, False); + } + + MI.eraseFromParent(); + return; + } + + // Fixup the case with an s1 src that isn't a condition register. Use shifts + // instead of introducing a compare to avoid an unnecessary condition + // register (and since there's no scalar 16-bit compares). + auto Ext = B.buildAnyExt(DstTy, SrcReg); + auto ShiftAmt = B.buildConstant(LLT::scalar(32), DstTy.getSizeInBits() - 1); + auto Shl = B.buildShl(DstTy, Ext, ShiftAmt); + + if (MI.getOpcode() == AMDGPU::G_SEXT) + B.buildAShr(DstReg, Shl, ShiftAmt); + else + B.buildLShr(DstReg, Shl, ShiftAmt); + + MRI.setRegBank(DstReg, *SrcBank); + MRI.setRegBank(Ext.getReg(0), *SrcBank); + MRI.setRegBank(ShiftAmt.getReg(0), *SrcBank); + MRI.setRegBank(Shl.getReg(0), *SrcBank); + MI.eraseFromParent(); + return; + } case AMDGPU::G_EXTRACT_VECTOR_ELT: applyDefaultMapping(OpdMapper); executeInWaterfallLoop(MI, MRI, { 2 }); @@ -1225,19 +1288,22 @@ unsigned Src = MI.getOperand(1).getReg(); unsigned DstSize = getSizeInBits(Dst, MRI, *TRI); unsigned SrcSize = getSizeInBits(Src, MRI, *TRI); - unsigned SrcBank = getRegBankID(Src, MRI, *TRI, - SrcSize == 1 ? AMDGPU::SGPRRegBankID : - AMDGPU::VGPRRegBankID); - unsigned DstBank = SrcBank; - if (SrcSize == 1) { - if (SrcBank == AMDGPU::SGPRRegBankID) - DstBank = AMDGPU::VGPRRegBankID; - else - DstBank = AMDGPU::SGPRRegBankID; + + unsigned DstBank; + const RegisterBank *SrcBank = getRegBank(Src, MRI, *TRI); + assert(SrcBank); + switch (SrcBank->getID()) { + case AMDGPU::SCCRegBankID: + case AMDGPU::SGPRRegBankID: + DstBank = AMDGPU::SGPRRegBankID; + break; + default: + DstBank = AMDGPU::VGPRRegBankID; + break; } OpdsMapping[0] = AMDGPU::getValueMapping(DstBank, DstSize); - OpdsMapping[1] = AMDGPU::getValueMapping(SrcBank, SrcSize); + OpdsMapping[1] = AMDGPU::getValueMapping(SrcBank->getID(), SrcSize); break; } case AMDGPU::G_FCMP: { Index: test/CodeGen/AMDGPU/GlobalISel/regbankselect-anyext.mir =================================================================== --- test/CodeGen/AMDGPU/GlobalISel/regbankselect-anyext.mir +++ test/CodeGen/AMDGPU/GlobalISel/regbankselect-anyext.mir @@ -3,29 +3,233 @@ # RUN: llc -march=amdgcn -mcpu=fiji -run-pass=regbankselect %s -verify-machineinstrs -o - -regbankselect-greedy | FileCheck %s --- -name: anyext_i32_to_i64_s +name: anyext_s32_to_s64_s legalized: true body: | bb.0: liveins: $sgpr0 - ; CHECK-LABEL: name: anyext_i32_to_i64_s + ; CHECK-LABEL: name: anyext_s32_to_s64_s ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 - ; CHECK: [[SEXT:%[0-9]+]]:sgpr(s64) = G_ANYEXT [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s64) = G_ANYEXT [[COPY]](s32) %0:_(s32) = COPY $sgpr0 %1:_(s64) = G_ANYEXT %0 ... --- -name: anyext_i32_to_i64_v +name: anyext_s32_to_s64_v legalized: true body: | bb.0: liveins: $vgpr0_vgpr1 - ; CHECK-LABEL: name: anyext_i32_to_i64_v + ; CHECK-LABEL: name: anyext_s32_to_s64_v ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 - ; CHECK: [[SEXT:%[0-9]+]]:vgpr(s64) = G_ANYEXT [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s64) = G_ANYEXT [[COPY]](s32) %0:_(s32) = COPY $vgpr0 %1:_(s64) = G_ANYEXT %0 ... + +--- +name: anyext_s1_to_s16_scc +legalized: true + +body: | + bb.0: + liveins: $sgpr0, $sgpr1 + ; CHECK-LABEL: name: anyext_s1_to_s16_scc + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:scc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s16) = G_ANYEXT [[ICMP]](s1) + %0:_(s32) = COPY $sgpr0 + %1:_(s32) = COPY $sgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s16) = G_ANYEXT %2 +... + +--- +name: anyext_s1_to_s32_scc +legalized: true + +body: | + bb.0: + liveins: $sgpr0, $sgpr1 + ; CHECK-LABEL: name: anyext_s1_to_s32_scc + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:scc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s32) = G_ANYEXT [[ICMP]](s1) + %0:_(s32) = COPY $sgpr0 + %1:_(s32) = COPY $sgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s32) = G_ANYEXT %2 +... + +--- +name: anyext_s1_to_s64_scc +legalized: true + +body: | + bb.0: + liveins: $sgpr0, $sgpr1 + ; CHECK-LABEL: name: anyext_s1_to_s64_scc + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:scc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s64) = G_ANYEXT [[ICMP]](s1) + %0:_(s32) = COPY $sgpr0 + %1:_(s32) = COPY $sgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s64) = G_ANYEXT %2 +... + +--- +name: anyext_s1_to_s16_vcc +legalized: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; CHECK-LABEL: name: anyext_s1_to_s16_vcc + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:vcc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s16) = G_ANYEXT [[ICMP]](s1) + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s16) = G_ANYEXT %2 +... + +--- +name: anyext_s1_to_s32_vcc +legalized: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; CHECK-LABEL: name: anyext_s1_to_s32_vcc + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:vcc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s32) = G_ANYEXT [[ICMP]](s1) + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s32) = G_ANYEXT %2 +... + +--- +name: anyext_s1_to_s64_vcc +legalized: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; CHECK-LABEL: name: anyext_s1_to_s64_vcc + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:vcc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s64) = G_ANYEXT [[ICMP]](s1) + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s64) = G_ANYEXT %2 +... + +--- +name: anyext_s1_to_s16_sgpr +legalized: true + +body: | + bb.0: + liveins: $sgpr0 + ; CHECK-LABEL: name: anyext_s1_to_s16_sgpr + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:sgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s16) = G_ANYEXT [[TRUNC]](s1) + %0:_(s32) = COPY $sgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s16) = G_ANYEXT %1 +... + +--- +name: anyext_s1_to_s32_sgpr +legalized: true + +body: | + bb.0: + liveins: $sgpr0 + ; CHECK-LABEL: name: anyext_s1_to_s32_sgpr + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:sgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s32) = G_ANYEXT [[TRUNC]](s1) + %0:_(s32) = COPY $sgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s32) = G_ANYEXT %1 +... + +--- +name: anyext_s1_to_s64_sgpr +legalized: true + +body: | + bb.0: + liveins: $sgpr0 + ; CHECK-LABEL: name: anyext_s1_to_s64_sgpr + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:sgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s64) = G_ANYEXT [[TRUNC]](s1) + %0:_(s32) = COPY $sgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s64) = G_ANYEXT %1 +... + +--- +name: anyext_s1_to_s16_vgpr +legalized: true + +body: | + bb.0: + liveins: $vgpr0 + ; CHECK-LABEL: name: anyext_s1_to_s16_vgpr + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s16) = G_ANYEXT [[TRUNC]](s1) + %0:_(s32) = COPY $vgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s16) = G_ANYEXT %1 +... + +--- +name: anyext_s1_to_s32_vgpr +legalized: true + +body: | + bb.0: + liveins: $vgpr0 + ; CHECK-LABEL: name: anyext_s1_to_s32_vgpr + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s32) = G_ANYEXT [[TRUNC]](s1) + %0:_(s32) = COPY $vgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s32) = G_ANYEXT %1 +... + +--- +name: anyext_s1_to_s64_vgpr +legalized: true + +body: | + bb.0: + liveins: $vgpr0 + ; CHECK-LABEL: name: anyext_s1_to_s64_vgpr + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s64) = G_ANYEXT [[TRUNC]](s1) + %0:_(s32) = COPY $vgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s64) = G_ANYEXT %1 +... Index: test/CodeGen/AMDGPU/GlobalISel/regbankselect-sext.mir =================================================================== --- test/CodeGen/AMDGPU/GlobalISel/regbankselect-sext.mir +++ test/CodeGen/AMDGPU/GlobalISel/regbankselect-sext.mir @@ -3,13 +3,13 @@ # RUN: llc -march=amdgcn -mcpu=fiji -run-pass=regbankselect %s -verify-machineinstrs -o - -regbankselect-greedy | FileCheck %s --- -name: zext_i32_to_i64_s +name: sext_s32_to_s64_s legalized: true body: | bb.0: liveins: $sgpr0 - ; CHECK-LABEL: name: zext_i32_to_i64_s + ; CHECK-LABEL: name: sext_s32_to_s64_s ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 ; CHECK: [[SEXT:%[0-9]+]]:sgpr(s64) = G_SEXT [[COPY]](s32) %0:_(s32) = COPY $sgpr0 @@ -17,15 +17,252 @@ ... --- -name: zext_i32_to_i64_v +name: sext_s32_to_s64_v legalized: true body: | bb.0: liveins: $vgpr0_vgpr1 - ; CHECK-LABEL: name: zext_i32_to_i64_v + ; CHECK-LABEL: name: sext_s32_to_s64_v ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 ; CHECK: [[SEXT:%[0-9]+]]:vgpr(s64) = G_SEXT [[COPY]](s32) %0:_(s32) = COPY $vgpr0 %1:_(s64) = G_SEXT %0 ... + +--- +name: sext_s1_to_s16_scc +legalized: true + +body: | + bb.0: + liveins: $sgpr0, $sgpr1 + ; CHECK-LABEL: name: sext_s1_to_s16_scc + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:scc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 -1 + ; CHECK: [[C1:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 0 + ; CHECK: [[SELECT:%[0-9]+]]:sgpr(s32) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + ; CHECK: [[TRUNC:%[0-9]+]]:sgpr(s16) = G_TRUNC [[SELECT]](s32) + %0:_(s32) = COPY $sgpr0 + %1:_(s32) = COPY $sgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s16) = G_SEXT %2 +... + +--- +name: sext_s1_to_s32_scc +legalized: true + +body: | + bb.0: + liveins: $sgpr0, $sgpr1 + ; CHECK-LABEL: name: sext_s1_to_s32_scc + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:scc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 -1 + ; CHECK: [[C1:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 0 + ; CHECK: [[SELECT:%[0-9]+]]:sgpr(s32) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + %0:_(s32) = COPY $sgpr0 + %1:_(s32) = COPY $sgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s32) = G_SEXT %2 +... + +--- +name: sext_s1_to_s64_scc +legalized: true + +body: | + bb.0: + liveins: $sgpr0, $sgpr1 + ; CHECK-LABEL: name: sext_s1_to_s64_scc + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:scc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 -1 + ; CHECK: [[C1:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 0 + ; CHECK: [[SELECT:%[0-9]+]]:sgpr(s64) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + %0:_(s32) = COPY $sgpr0 + %1:_(s32) = COPY $sgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s64) = G_SEXT %2 +... + +--- +name: sext_s1_to_s16_vcc +legalized: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; CHECK-LABEL: name: sext_s1_to_s16_vcc + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:vcc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 -1 + ; CHECK: [[C1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0 + ; CHECK: [[SELECT:%[0-9]+]]:vgpr(s32) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + ; CHECK: [[TRUNC:%[0-9]+]]:vgpr(s16) = G_TRUNC [[SELECT]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s16) = G_SEXT %2 +... + +--- +name: sext_s1_to_s32_vcc +legalized: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; CHECK-LABEL: name: sext_s1_to_s32_vcc + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:vcc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 -1 + ; CHECK: [[C1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0 + ; CHECK: [[SELECT:%[0-9]+]]:vgpr(s32) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s32) = G_SEXT %2 +... + +--- +name: sext_s1_to_s64_vcc +legalized: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; CHECK-LABEL: name: sext_s1_to_s64_vcc + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:vcc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 -1 + ; CHECK: [[C1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0 + ; CHECK: [[SELECT:%[0-9]+]]:vgpr(s32) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + ; CHECK: [[MV:%[0-9]+]]:vgpr(s64) = G_MERGE_VALUES [[SELECT]](s32), [[SELECT]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s64) = G_SEXT %2 +... + +--- +name: sext_s1_to_s16_sgpr +legalized: true + +body: | + bb.0: + liveins: $sgpr0 + ; CHECK-LABEL: name: sext_s1_to_s16_sgpr + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:sgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s16) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 15 + ; CHECK: [[SHL:%[0-9]+]]:sgpr(s16) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[ASHR:%[0-9]+]]:sgpr(s16) = G_ASHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $sgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s16) = G_SEXT %1 +... + +--- +name: sext_s1_to_s32_sgpr +legalized: true + +body: | + bb.0: + liveins: $sgpr0 + ; CHECK-LABEL: name: sext_s1_to_s32_sgpr + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:sgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s32) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 31 + ; CHECK: [[SHL:%[0-9]+]]:sgpr(s32) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[ASHR:%[0-9]+]]:sgpr(s32) = G_ASHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $sgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s32) = G_SEXT %1 +... + +--- +name: sext_s1_to_s64_sgpr +legalized: true + +body: | + bb.0: + liveins: $sgpr0 + ; CHECK-LABEL: name: sext_s1_to_s64_sgpr + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:sgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s64) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 63 + ; CHECK: [[SHL:%[0-9]+]]:sgpr(s64) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[ASHR:%[0-9]+]]:sgpr(s64) = G_ASHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $sgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s64) = G_SEXT %1 +... + +--- +name: sext_s1_to_s16_vgpr +legalized: true + +body: | + bb.0: + liveins: $vgpr0 + ; CHECK-LABEL: name: sext_s1_to_s16_vgpr + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s16) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 15 + ; CHECK: [[SHL:%[0-9]+]]:vgpr(s16) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[ASHR:%[0-9]+]]:vgpr(s16) = G_ASHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s16) = G_SEXT %1 +... + +--- +name: sext_s1_to_s32_vgpr +legalized: true + +body: | + bb.0: + liveins: $vgpr0 + ; CHECK-LABEL: name: sext_s1_to_s32_vgpr + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s32) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 31 + ; CHECK: [[SHL:%[0-9]+]]:vgpr(s32) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[ASHR:%[0-9]+]]:vgpr(s32) = G_ASHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s32) = G_SEXT %1 +... + +--- +name: sext_s1_to_s64_vgpr +legalized: true + +body: | + bb.0: + liveins: $vgpr0 + ; CHECK-LABEL: name: sext_s1_to_s64_vgpr + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s64) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 63 + ; CHECK: [[SHL:%[0-9]+]]:vgpr(s64) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[ASHR:%[0-9]+]]:vgpr(s64) = G_ASHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s64) = G_SEXT %1 +... Index: test/CodeGen/AMDGPU/GlobalISel/regbankselect-zext.mir =================================================================== --- test/CodeGen/AMDGPU/GlobalISel/regbankselect-zext.mir +++ test/CodeGen/AMDGPU/GlobalISel/regbankselect-zext.mir @@ -3,13 +3,13 @@ # RUN: llc -march=amdgcn -mcpu=fiji -run-pass=regbankselect %s -verify-machineinstrs -o - -regbankselect-greedy | FileCheck %s --- -name: zext_i32_to_i64_s +name: zext_s32_to_s64_s legalized: true body: | bb.0: liveins: $sgpr0 - ; CHECK-LABEL: name: zext_i32_to_i64_s + ; CHECK-LABEL: name: zext_s32_to_s64_s ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 ; CHECK: [[ZEXT:%[0-9]+]]:sgpr(s64) = G_ZEXT [[COPY]](s32) %0:_(s32) = COPY $sgpr0 @@ -17,15 +17,252 @@ ... --- -name: zext_i32_to_i64_v +name: zext_s32_to_s64_v legalized: true body: | bb.0: liveins: $vgpr0_vgpr1 - ; CHECK-LABEL: name: zext_i32_to_i64_v + ; CHECK-LABEL: name: zext_s32_to_s64_v ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 ; CHECK: [[ZEXT:%[0-9]+]]:vgpr(s64) = G_ZEXT [[COPY]](s32) %0:_(s32) = COPY $vgpr0 %1:_(s64) = G_ZEXT %0 ... + +--- +name: zext_s1_to_s16_scc +legalized: true + +body: | + bb.0: + liveins: $sgpr0, $sgpr1 + ; CHECK-LABEL: name: zext_s1_to_s16_scc + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:scc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 1 + ; CHECK: [[C1:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 0 + ; CHECK: [[SELECT:%[0-9]+]]:sgpr(s32) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + ; CHECK: [[TRUNC:%[0-9]+]]:sgpr(s16) = G_TRUNC [[SELECT]](s32) + %0:_(s32) = COPY $sgpr0 + %1:_(s32) = COPY $sgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s16) = G_ZEXT %2 +... + +--- +name: zext_s1_to_s32_scc +legalized: true + +body: | + bb.0: + liveins: $sgpr0, $sgpr1 + ; CHECK-LABEL: name: zext_s1_to_s32_scc + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:scc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 1 + ; CHECK: [[C1:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 0 + ; CHECK: [[SELECT:%[0-9]+]]:sgpr(s32) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + %0:_(s32) = COPY $sgpr0 + %1:_(s32) = COPY $sgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s32) = G_ZEXT %2 +... + +--- +name: zext_s1_to_s64_scc +legalized: true + +body: | + bb.0: + liveins: $sgpr0, $sgpr1 + ; CHECK-LABEL: name: zext_s1_to_s64_scc + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:scc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 1 + ; CHECK: [[C1:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 0 + ; CHECK: [[SELECT:%[0-9]+]]:sgpr(s64) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + %0:_(s32) = COPY $sgpr0 + %1:_(s32) = COPY $sgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s64) = G_ZEXT %2 +... + +--- +name: zext_s1_to_s16_vcc +legalized: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; CHECK-LABEL: name: zext_s1_to_s16_vcc + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:vcc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 1 + ; CHECK: [[C1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0 + ; CHECK: [[SELECT:%[0-9]+]]:vgpr(s32) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + ; CHECK: [[TRUNC:%[0-9]+]]:vgpr(s16) = G_TRUNC [[SELECT]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s16) = G_ZEXT %2 +... + +--- +name: zext_s1_to_s32_vcc +legalized: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; CHECK-LABEL: name: zext_s1_to_s32_vcc + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:vcc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 1 + ; CHECK: [[C1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0 + ; CHECK: [[SELECT:%[0-9]+]]:vgpr(s32) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s32) = G_ZEXT %2 +... + +--- +name: zext_s1_to_s64_vcc +legalized: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; CHECK-LABEL: name: zext_s1_to_s64_vcc + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[ICMP:%[0-9]+]]:vcc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 1 + ; CHECK: [[C1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0 + ; CHECK: [[SELECT:%[0-9]+]]:vgpr(s32) = G_SELECT [[ICMP]](s1), [[C]], [[C1]] + ; CHECK: [[MV:%[0-9]+]]:vgpr(s64) = G_MERGE_VALUES [[SELECT]](s32), [[SELECT]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s1) = G_ICMP intpred(eq), %0, %1 + %3:_(s64) = G_ZEXT %2 +... + +--- +name: zext_s1_to_s16_sgpr +legalized: true + +body: | + bb.0: + liveins: $sgpr0 + ; CHECK-LABEL: name: zext_s1_to_s16_sgpr + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:sgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s16) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 15 + ; CHECK: [[SHL:%[0-9]+]]:sgpr(s16) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[LSHR:%[0-9]+]]:sgpr(s16) = G_LSHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $sgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s16) = G_ZEXT %1 +... + +--- +name: zext_s1_to_s32_sgpr +legalized: true + +body: | + bb.0: + liveins: $sgpr0 + ; CHECK-LABEL: name: zext_s1_to_s32_sgpr + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:sgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s32) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 31 + ; CHECK: [[SHL:%[0-9]+]]:sgpr(s32) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[LSHR:%[0-9]+]]:sgpr(s32) = G_LSHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $sgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s32) = G_ZEXT %1 +... + +--- +name: zext_s1_to_s64_sgpr +legalized: true + +body: | + bb.0: + liveins: $sgpr0 + ; CHECK-LABEL: name: zext_s1_to_s64_sgpr + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:sgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:sgpr(s64) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 63 + ; CHECK: [[SHL:%[0-9]+]]:sgpr(s64) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[LSHR:%[0-9]+]]:sgpr(s64) = G_LSHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $sgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s64) = G_ZEXT %1 +... + +--- +name: zext_s1_to_s16_vgpr +legalized: true + +body: | + bb.0: + liveins: $vgpr0 + ; CHECK-LABEL: name: zext_s1_to_s16_vgpr + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s16) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 15 + ; CHECK: [[SHL:%[0-9]+]]:vgpr(s16) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[LSHR:%[0-9]+]]:vgpr(s16) = G_LSHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s16) = G_ZEXT %1 +... + +--- +name: zext_s1_to_s32_vgpr +legalized: true + +body: | + bb.0: + liveins: $vgpr0 + ; CHECK-LABEL: name: zext_s1_to_s32_vgpr + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s32) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 31 + ; CHECK: [[SHL:%[0-9]+]]:vgpr(s32) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[LSHR:%[0-9]+]]:vgpr(s32) = G_LSHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s32) = G_ZEXT %1 +... + +--- +name: zext_s1_to_s64_vgpr +legalized: true + +body: | + bb.0: + liveins: $vgpr0 + ; CHECK-LABEL: name: zext_s1_to_s64_vgpr + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32) + ; CHECK: [[ANYEXT:%[0-9]+]]:vgpr(s64) = G_ANYEXT [[TRUNC]](s1) + ; CHECK: [[C:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 63 + ; CHECK: [[SHL:%[0-9]+]]:vgpr(s64) = G_SHL [[ANYEXT]], [[C]](s32) + ; CHECK: [[LSHR:%[0-9]+]]:vgpr(s64) = G_LSHR [[SHL]], [[C]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s1) = G_TRUNC %0 + %2:_(s64) = G_ZEXT %1 +...