llvm.org GIT mirror llvm / b2b237d
[X86] When promoting i16 compare with immediate to i32, try to use sign_extend for eq/ne if the input is truncated from a type with enough sign its. Summary: Our default behavior is to use sign_extend for signed comparisons and zero_extend for everything else. But for equality we have the freedom to use either extension. If we can prove the input has been truncated from something with enough sign bits, we can use sign_extend instead and let DAG combine optimize it out. A similar rule is used by type legalization in LegalizeIntegerTypes. This gets rid of the movzx in PR42189. The immediate will still take 4 bytes instead of the 2 bytes plus 0x66 prefix a cmp di, 32767 would get, but it avoids a length changing prefix. Reviewers: RKSimon, spatel, xbolva00 Reviewed By: xbolva00 Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63032 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362920 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 4 months ago
2 changed file(s) with 83 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
1949019490 if (isNullConstant(Op1))
1949119491 return EmitTest(Op0, X86CC, dl, DAG, Subtarget);
1949219492
19493 if ((Op0.getValueType() == MVT::i8 || Op0.getValueType() == MVT::i16 ||
19494 Op0.getValueType() == MVT::i32 || Op0.getValueType() == MVT::i64)) {
19495 // Only promote the compare up to I32 if it is a 16 bit operation
19496 // with an immediate. 16 bit immediates are to be avoided.
19497 if (Op0.getValueType() == MVT::i16 &&
19498 ((isa(Op0) &&
19499 !cast(Op0)->getAPIntValue().isSignedIntN(8)) ||
19500 (isa(Op1) &&
19501 !cast(Op1)->getAPIntValue().isSignedIntN(8))) &&
19502 !DAG.getMachineFunction().getFunction().hasMinSize() &&
19503 !Subtarget.isAtom()) {
19493 EVT CmpVT = Op0.getValueType();
19494
19495 if (CmpVT.isFloatingPoint())
19496 return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op0, Op1);
19497
19498 assert((CmpVT == MVT::i8 || CmpVT == MVT::i16 ||
19499 CmpVT == MVT::i32 || CmpVT == MVT::i64) && "Unexpected VT!");
19500
19501 // Only promote the compare up to I32 if it is a 16 bit operation
19502 // with an immediate. 16 bit immediates are to be avoided.
19503 if (CmpVT == MVT::i16 && !Subtarget.isAtom() &&
19504 !DAG.getMachineFunction().getFunction().hasMinSize()) {
19505 ConstantSDNode *COp0 = dyn_cast(Op0);
19506 ConstantSDNode *COp1 = dyn_cast(Op1);
19507 // Don't do this if the immediate can fit in 8-bits.
19508 if ((COp0 && !COp0->getAPIntValue().isSignedIntN(8)) ||
19509 (COp1 && !COp1->getAPIntValue().isSignedIntN(8))) {
1950419510 unsigned ExtendOp =
1950519511 isX86CCUnsigned(X86CC) ? ISD::ZERO_EXTEND : ISD::SIGN_EXTEND;
19506 Op0 = DAG.getNode(ExtendOp, dl, MVT::i32, Op0);
19507 Op1 = DAG.getNode(ExtendOp, dl, MVT::i32, Op1);
19508 }
19509 // Use SUB instead of CMP to enable CSE between SUB and CMP.
19510 SDVTList VTs = DAG.getVTList(Op0.getValueType(), MVT::i32);
19511 SDValue Sub = DAG.getNode(X86ISD::SUB, dl, VTs, Op0, Op1);
19512 return SDValue(Sub.getNode(), 1);
19513 }
19514 assert(Op0.getValueType().isFloatingPoint() && "Unexpected VT!");
19515 return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op0, Op1);
19512 if (X86CC == X86::COND_E || X86CC == X86::COND_NE) {
19513 // For equality comparisons try to use SIGN_EXTEND if the input was
19514 // truncate from something with enough sign bits.
19515 if (Op0.getOpcode() == ISD::TRUNCATE) {
19516 SDValue In = Op0.getOperand(0);
19517 unsigned EffBits =
19518 In.getScalarValueSizeInBits() - DAG.ComputeNumSignBits(In) + 1;
19519 if (EffBits <= 16)
19520 ExtendOp = ISD::SIGN_EXTEND;
19521 } else if (Op1.getOpcode() == ISD::TRUNCATE) {
19522 SDValue In = Op1.getOperand(0);
19523 unsigned EffBits =
19524 In.getScalarValueSizeInBits() - DAG.ComputeNumSignBits(In) + 1;
19525 if (EffBits <= 16)
19526 ExtendOp = ISD::SIGN_EXTEND;
19527 }
19528 }
19529
19530 CmpVT = MVT::i32;
19531 Op0 = DAG.getNode(ExtendOp, dl, CmpVT, Op0);
19532 Op1 = DAG.getNode(ExtendOp, dl, CmpVT, Op1);
19533 }
19534 }
19535 // Use SUB instead of CMP to enable CSE between SUB and CMP.
19536 SDVTList VTs = DAG.getVTList(CmpVT, MVT::i32);
19537 SDValue Sub = DAG.getNode(X86ISD::SUB, dl, VTs, Op0, Op1);
19538 return Sub.getValue(1);
1951619539 }
1951719540
1951819541 /// Convert a comparison if required by the subtarget.
482482 %9 = insertvalue { i64, i64 } %8, i64 %6, 1
483483 ret { i64, i64 } %9
484484 }
485
486 ; Make sure we use a 32-bit comparison without an extend based on the input
487 ; being pre-sign extended by caller.
488 define i32 @pr42189(i16 signext %c) {
489 ; CHECK-LABEL: pr42189:
490 ; CHECK: # %bb.0: # %entry
491 ; CHECK-NEXT: cmpl $32767, %edi # encoding: [0x81,0xff,0xff,0x7f,0x00,0x00]
492 ; CHECK-NEXT: # imm = 0x7FFF
493 ; CHECK-NEXT: jne .LBB26_2 # encoding: [0x75,A]
494 ; CHECK-NEXT: # fixup A - offset: 1, value: .LBB26_2-1, kind: FK_PCRel_1
495 ; CHECK-NEXT: # %bb.1: # %if.then
496 ; CHECK-NEXT: jmp g # TAILCALL
497 ; CHECK-NEXT: # encoding: [0xeb,A]
498 ; CHECK-NEXT: # fixup A - offset: 1, value: g-1, kind: FK_PCRel_1
499 ; CHECK-NEXT: .LBB26_2: # %if.end
500 ; CHECK-NEXT: jmp f # TAILCALL
501 ; CHECK-NEXT: # encoding: [0xeb,A]
502 ; CHECK-NEXT: # fixup A - offset: 1, value: f-1, kind: FK_PCRel_1
503 entry:
504 %cmp = icmp eq i16 %c, 32767
505 br i1 %cmp, label %if.then, label %if.end
506
507 if.then: ; preds = %entry
508 %call = tail call i32 @g()
509 br label %return
510
511 if.end: ; preds = %entry
512 %call2 = tail call i32 @f()
513 br label %return
514
515 return: ; preds = %if.end, %if.then
516 %retval.0 = phi i32 [ %call, %if.then ], [ %call2, %if.end ]
517 ret i32 %retval.0
518 }
519
520 declare i32 @g()
521
522 declare i32 @f()
523