@@ -4289,19 +4289,23 @@ enum srcStatus {
42894289 IS_NEG,
42904290 IS_UPPER_HALF_NEG,
42914291 IS_LOWER_HALF_NEG,
4292- LAST_STAT = IS_LOWER_HALF_NEG
4292+ INVALID
42934293};
42944294
42954295static bool isTruncHalf (const MachineInstr *MI,
42964296 const MachineRegisterInfo &MRI) {
4297- assert (MI->getOpcode () == AMDGPU::G_TRUNC);
4297+ if (MI->getOpcode () != AMDGPU::G_TRUNC) {
4298+ return false ;
4299+ }
42984300 unsigned dstSize = MRI.getType (MI->getOperand (0 ).getReg ()).getSizeInBits ();
42994301 unsigned srcSize = MRI.getType (MI->getOperand (1 ).getReg ()).getSizeInBits ();
43004302 return dstSize * 2 == srcSize;
43014303}
43024304
43034305static bool isLshrHalf (const MachineInstr *MI, const MachineRegisterInfo &MRI) {
4304- assert (MI->getOpcode () == AMDGPU::G_LSHR);
4306+ if (MI->getOpcode () != AMDGPU::G_LSHR) {
4307+ return false ;
4308+ }
43054309 Register ShiftSrc;
43064310 std::optional<ValueAndVReg> ShiftAmt;
43074311 if (mi_match (MI->getOperand (0 ).getReg (), MRI,
@@ -4314,7 +4318,9 @@ static bool isLshrHalf(const MachineInstr *MI, const MachineRegisterInfo &MRI) {
43144318}
43154319
43164320static bool isShlHalf (const MachineInstr *MI, const MachineRegisterInfo &MRI) {
4317- assert (MI->getOpcode () == AMDGPU::G_SHL);
4321+ if (MI->getOpcode () != AMDGPU::G_SHL) {
4322+ return false ;
4323+ }
43184324 Register ShiftSrc;
43194325 std::optional<ValueAndVReg> ShiftAmt;
43204326 if (mi_match (MI->getOperand (0 ).getReg (), MRI,
@@ -4326,8 +4332,11 @@ static bool isShlHalf(const MachineInstr *MI, const MachineRegisterInfo &MRI) {
43264332 return false ;
43274333}
43284334
4329- static bool retOpStat (const MachineOperand *Op, int stat,
4330- std::pair<const MachineOperand *, int > &curr) {
4335+ static bool retOpStat (const MachineOperand *Op, srcStatus stat,
4336+ std::pair<const MachineOperand *, srcStatus> &curr) {
4337+ if (stat == INVALID) {
4338+ return false ;
4339+ }
43314340 if ((Op->isReg () && !(Op->getReg ().isPhysical ())) || Op->isImm () ||
43324341 Op->isCImm () || Op->isFPImm ()) {
43334342 curr = {Op, stat};
@@ -4336,7 +4345,25 @@ static bool retOpStat(const MachineOperand *Op, int stat,
43364345 return false ;
43374346}
43384347
4339- static bool calcNextStatus (std::pair<const MachineOperand *, int > &curr,
4348+ srcStatus getNegStatus (srcStatus S) {
4349+ switch (S) {
4350+ case IS_SAME:
4351+ return IS_NEG;
4352+ case IS_UPPER_HALF:
4353+ return IS_UPPER_HALF_NEG;
4354+ case IS_LOWER_HALF:
4355+ return IS_LOWER_HALF_NEG;
4356+ case IS_NEG:
4357+ return IS_SAME;
4358+ case IS_UPPER_HALF_NEG:
4359+ return IS_UPPER_HALF;
4360+ case IS_LOWER_HALF_NEG:
4361+ return IS_LOWER_HALF;
4362+ }
4363+ return INVALID;
4364+ }
4365+
4366+ static bool calcNextStatus (std::pair<const MachineOperand *, srcStatus> &curr,
43404367 const MachineRegisterInfo &MRI) {
43414368 if (!curr.first ->isReg ()) {
43424369 return false ;
@@ -4363,92 +4390,56 @@ static bool calcNextStatus(std::pair<const MachineOperand *, int> &curr,
43634390 return retOpStat (&MI->getOperand (1 ), curr.second , curr);
43644391 case AMDGPU::G_FNEG:
43654392 // XXXX + 3 = XXXX_NEG, (XXXX_NEG + 3) mod 3 = XXXX
4366- return retOpStat (&MI->getOperand (1 ),
4367- (curr.second + ((LAST_STAT + 1 ) / 2 )) % (LAST_STAT + 1 ),
4368- curr);
4393+ return retOpStat (&MI->getOperand (1 ), getNegStatus (curr.second ), curr);
43694394 }
43704395
43714396 // Calc next stat from current stat
43724397 switch (curr.second ) {
43734398 case IS_SAME:
4374- switch (Opc) {
4375- case AMDGPU::G_TRUNC: {
4376- if (isTruncHalf (MI, MRI)) {
4377- return retOpStat (&MI->getOperand (1 ), IS_LOWER_HALF, curr);
4378- }
4379- break ;
4380- }
4399+ if (isTruncHalf (MI, MRI)) {
4400+ return retOpStat (&MI->getOperand (1 ), IS_LOWER_HALF, curr);
43814401 }
43824402 break ;
43834403 case IS_NEG:
4384- switch (Opc) {
4385- case AMDGPU::G_TRUNC: {
4386- if (isTruncHalf (MI, MRI)) {
4387- return retOpStat (&MI->getOperand (1 ), IS_LOWER_HALF_NEG, curr);
4388- }
4389- break ;
4390- }
4404+ if (isTruncHalf (MI, MRI)) {
4405+ return retOpStat (&MI->getOperand (1 ), IS_LOWER_HALF_NEG, curr);
43914406 }
43924407 break ;
43934408 case IS_UPPER_HALF:
4394- switch (Opc) {
4395- case AMDGPU::G_SHL: {
4396- if (isShlHalf (MI, MRI)) {
4397- return retOpStat (&MI->getOperand (1 ), IS_LOWER_HALF, curr);
4398- }
4399- break ;
4400- }
4409+ if (isShlHalf (MI, MRI)) {
4410+ return retOpStat (&MI->getOperand (1 ), IS_LOWER_HALF, curr);
44014411 }
44024412 break ;
44034413 case IS_LOWER_HALF:
4404- switch (Opc) {
4405- case AMDGPU::G_LSHR: {
4406- if (isLshrHalf (MI, MRI)) {
4407- return retOpStat (&MI->getOperand (1 ), IS_UPPER_HALF, curr);
4408- }
4409- break ;
4410- }
4414+ if (isLshrHalf (MI, MRI)) {
4415+ return retOpStat (&MI->getOperand (1 ), IS_UPPER_HALF, curr);
44114416 }
44124417 break ;
44134418 case IS_UPPER_HALF_NEG:
4414- switch (Opc) {
4415- case AMDGPU::G_SHL: {
4416- if (isShlHalf (MI, MRI)) {
4417- return retOpStat (&MI->getOperand (1 ), IS_LOWER_HALF_NEG, curr);
4418- }
4419- break ;
4420- }
4419+ if (isShlHalf (MI, MRI)) {
4420+ return retOpStat (&MI->getOperand (1 ), IS_LOWER_HALF_NEG, curr);
44214421 }
44224422 break ;
44234423 case IS_LOWER_HALF_NEG:
4424- switch (Opc) {
4425- case AMDGPU::G_LSHR: {
4426- if (isLshrHalf (MI, MRI)) {
4427- return retOpStat (&MI->getOperand (1 ), IS_UPPER_HALF_NEG, curr);
4428- }
4429- break ;
4430- }
4424+ if (isLshrHalf (MI, MRI)) {
4425+ return retOpStat (&MI->getOperand (1 ), IS_UPPER_HALF_NEG, curr);
44314426 }
44324427 break ;
44334428 }
44344429 return false ;
44354430}
44364431
4437- SmallVector<std::pair<const MachineOperand *, int >>
4432+ SmallVector<std::pair<const MachineOperand *, srcStatus >>
44384433getSrcStats (const MachineOperand *Op, const MachineRegisterInfo &MRI,
44394434 bool onlyLastSameOrNeg = false , int maxDepth = 6 ) {
44404435 int depth = 0 ;
4441- std::pair<const MachineOperand *, int > curr = {Op, IS_SAME};
4442- SmallVector<std::pair<const MachineOperand *, int >> statList;
4436+ std::pair<const MachineOperand *, srcStatus > curr = {Op, IS_SAME};
4437+ SmallVector<std::pair<const MachineOperand *, srcStatus >> statList;
44434438
4444- while (true ) {
4439+ while (depth <= maxDepth && calcNextStatus (curr, MRI) ) {
44454440 depth++;
4446- if (depth > maxDepth) {
4447- break ;
4448- }
4449- bool ret = calcNextStatus (curr, MRI);
4450- if (!ret || (onlyLastSameOrNeg &&
4451- (curr.second != IS_SAME && curr.second != IS_NEG))) {
4441+ if ((onlyLastSameOrNeg &&
4442+ (curr.second != IS_SAME && curr.second != IS_NEG))) {
44524443 break ;
44534444 } else if (!onlyLastSameOrNeg) {
44544445 statList.push_back (curr);
@@ -4535,7 +4526,8 @@ AMDGPUInstructionSelector::selectVOP3PModsImpl(const MachineOperand *Op,
45354526 bool IsDOT) const {
45364527 unsigned Mods = 0 ;
45374528 const MachineOperand *RootOp = Op;
4538- std::pair<const MachineOperand *, int > stat = getSrcStats (Op, MRI, true )[0 ];
4529+ std::pair<const MachineOperand *, srcStatus> stat =
4530+ getSrcStats (Op, MRI, true )[0 ];
45394531 if (!stat.first ->isReg ()) {
45404532 Mods |= SISrcMods::OP_SEL_1;
45414533 return {Op, Mods};
@@ -4547,8 +4539,8 @@ AMDGPUInstructionSelector::selectVOP3PModsImpl(const MachineOperand *Op,
45474539 MachineInstr *MI = MRI.getVRegDef (Op->getReg ());
45484540 if (MI->getOpcode () == AMDGPU::G_BUILD_VECTOR && MI->getNumOperands () == 3 &&
45494541 (!IsDOT || !Subtarget->hasDOTOpSelHazard ())) {
4550- SmallVector<std::pair<const MachineOperand *, int >> statList_Hi;
4551- SmallVector<std::pair<const MachineOperand *, int >> statList_Lo;
4542+ SmallVector<std::pair<const MachineOperand *, srcStatus >> statList_Hi;
4543+ SmallVector<std::pair<const MachineOperand *, srcStatus >> statList_Lo;
45524544 statList_Hi = getSrcStats (&MI->getOperand (2 ), MRI);
45534545 if (statList_Hi.size () != 0 ) {
45544546 statList_Lo = getSrcStats (&MI->getOperand (1 ), MRI);
0 commit comments