Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 601

Show
Ignore:
Timestamp:
08/05/10 21:21:50 (14 years ago)
Author:
walter
Message:

bugzilla 4443 Optimizer produces wrong code for or && with struct arrays

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/backend/cod2.c

    r596 r601  
    342342                        case 40:        ss = 2; ss2 = 3;        break; 
    343343                        case 18:        ss = 3;                 break; 
    344344                        case 36:        ss = 3; ss2 = 2;        break; 
    345345                        case 72:        ss = 3; ss2 = 3;        break; 
    346346                        default: 
    347347                            ss2 = 0; 
    348348                            goto L13; 
    349349                    } 
    350350                } 
    351351                freenode(e11->E2); 
    352352                freenode(e11); 
    353353                e11 = e11->E1; 
    354354                goto L13; 
    355355            } 
    356356            else 
    357357            { 
    358358            L13: 
    359359                regm_t regm; 
    360360                if (e11->Eoper == OPvar && isregvar(e11,&regm,&reg1)) 
    361361                { 
    362                     retregs = regm; 
     362                    if (tysize[tybasic(e11->Ety)]<= REGSIZE) 
     363                        retregs = mask[reg1]; // only want the LSW 
     364                    else 
     365                        retregs = regm; 
    363366                    c1 = NULL; 
    364367                    freenode(e11); 
    365368                } 
    366369                else 
    367370                    c1 = codelem(e11,&retregs,FALSE); 
    368371            } 
    369372            rretregs = ALLREGS & ~retregs; 
    370373            c2 = scodelem(ebase,&rretregs,retregs,TRUE); 
    371374            { 
    372375                regm_t sregs = *pretregs & ~rretregs; 
    373376                if (!sregs) 
    374377                    sregs = ALLREGS & ~rretregs; 
    375378                c3 = allocreg(&sregs,&reg,ty); 
    376379            } 
     380 
     381            assert((retregs & (retregs - 1)) == 0); // must be only one register 
     382            assert((rretregs & (rretregs - 1)) == 0); // must be only one register 
    377383 
    378384            reg1 = findreg(retregs); 
    379385            reg2 = findreg(rretregs); 
    380386 
    381387            if (ss2) 
    382388            { 
    383389                assert(reg != reg2); 
    384390                if (reg1 == BP) 
    385391                {   static unsigned imm32[4] = {1+1,2+1,4+1,8+1}; 
    386392 
    387393                    // IMUL reg,imm32 
    388394                    c = genc2(CNIL,0x69,modregxrm(3,reg,BP),imm32[ss]); 
    389395                } 
    390396                else 
    391397                {   // LEA reg,[reg1*ss][reg1] 
    392398                    c = gen2sib(CNIL,0x8D,modregxrm(0,reg,4),modregrm(ss,reg1 & 7,reg1 & 7)); 
    393399                    if (reg1 & 8) 
    394400                        code_orrex(c, REX_X | REX_B); 
    395401                } 
    396402                reg1 = reg; 
  • trunk/src/backend/cod2.c

    r596 r601  
    342342                        case 40:        ss = 2; ss2 = 3;        break; 
    343343                        case 18:        ss = 3;                 break; 
    344344                        case 36:        ss = 3; ss2 = 2;        break; 
    345345                        case 72:        ss = 3; ss2 = 3;        break; 
    346346                        default: 
    347347                            ss2 = 0; 
    348348                            goto L13; 
    349349                    } 
    350350                } 
    351351                freenode(e11->E2); 
    352352                freenode(e11); 
    353353                e11 = e11->E1; 
    354354                goto L13; 
    355355            } 
    356356            else 
    357357            { 
    358358            L13: 
    359359                regm_t regm; 
    360360                if (e11->Eoper == OPvar && isregvar(e11,&regm,&reg1)) 
    361361                { 
    362                     retregs = regm; 
     362                    if (tysize[tybasic(e11->Ety)]<= REGSIZE) 
     363                        retregs = mask[reg1]; // only want the LSW 
     364                    else 
     365                        retregs = regm; 
    363366                    c1 = NULL; 
    364367                    freenode(e11); 
    365368                } 
    366369                else 
    367370                    c1 = codelem(e11,&retregs,FALSE); 
    368371            } 
    369372            rretregs = ALLREGS & ~retregs; 
    370373            c2 = scodelem(ebase,&rretregs,retregs,TRUE); 
    371374            { 
    372375                regm_t sregs = *pretregs & ~rretregs; 
    373376                if (!sregs) 
    374377                    sregs = ALLREGS & ~rretregs; 
    375378                c3 = allocreg(&sregs,&reg,ty); 
    376379            } 
     380 
     381            assert((retregs & (retregs - 1)) == 0); // must be only one register 
     382            assert((rretregs & (rretregs - 1)) == 0); // must be only one register 
    377383 
    378384            reg1 = findreg(retregs); 
    379385            reg2 = findreg(rretregs); 
    380386 
    381387            if (ss2) 
    382388            { 
    383389                assert(reg != reg2); 
    384390                if (reg1 == BP) 
    385391                {   static unsigned imm32[4] = {1+1,2+1,4+1,8+1}; 
    386392 
    387393                    // IMUL reg,imm32 
    388394                    c = genc2(CNIL,0x69,modregxrm(3,reg,BP),imm32[ss]); 
    389395                } 
    390396                else 
    391397                {   // LEA reg,[reg1*ss][reg1] 
    392398                    c = gen2sib(CNIL,0x8D,modregxrm(0,reg,4),modregrm(ss,reg1 & 7,reg1 & 7)); 
    393399                    if (reg1 & 8) 
    394400                        code_orrex(c, REX_X | REX_B); 
    395401                } 
    396402                reg1 = reg;