@@ -3052,70 +3052,55 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
3052
3052
if (!C) break ;
3053
3053
uint64_t Mask = C->getZExtValue ();
3054
3054
3055
- // For example, convert "testl %eax, $8" to "testb %al, $8"
3055
+ MVT VT;
3056
+ int SubRegOp;
3057
+ unsigned Op;
3058
+
3056
3059
if (isUInt<8 >(Mask) &&
3057
3060
(!(Mask & 0x80 ) || hasNoSignedComparisonUses (Node))) {
3058
- SDValue Imm = CurDAG->getTargetConstant (Mask, dl, MVT::i8);
3059
- SDValue Reg = N0.getOperand (0 );
3060
-
3061
- // Extract the l-register.
3062
- SDValue Subreg = CurDAG->getTargetExtractSubreg (X86::sub_8bit, dl,
3063
- MVT::i8, Reg);
3064
-
3065
- // Emit a testb.
3066
- SDNode *NewNode = CurDAG->getMachineNode (X86::TEST8ri, dl, MVT::i32,
3067
- Subreg, Imm);
3068
- // Replace SUB|CMP with TEST, since SUB has two outputs while TEST has
3069
- // one, do not call ReplaceAllUsesWith.
3070
- ReplaceUses (SDValue (Node, (Opcode == X86ISD::SUB ? 1 : 0 )),
3071
- SDValue (NewNode, 0 ));
3072
- CurDAG->RemoveDeadNode (Node);
3073
- return ;
3061
+ // For example, convert "testl %eax, $8" to "testb %al, $8"
3062
+ VT = MVT::i8;
3063
+ SubRegOp = X86::sub_8bit;
3064
+ Op = X86::TEST8ri;
3065
+ } else if (OptForMinSize && isUInt<16 >(Mask) &&
3066
+ (!(Mask & 0x8000 ) || hasNoSignedComparisonUses (Node))) {
3067
+ // For example, "testl %eax, $32776" to "testw %ax, $32776".
3068
+ // NOTE: We only want to form TESTW instructions if optimizing for
3069
+ // min size. Otherwise we only save one byte and possibly get a length
3070
+ // changing prefix penalty in the decoders.
3071
+ VT = MVT::i16;
3072
+ SubRegOp = X86::sub_16bit;
3073
+ Op = X86::TEST16ri;
3074
+ } else if (isUInt<32 >(Mask) && N0.getValueType () != MVT::i16 &&
3075
+ (!(Mask & 0x80000000 ) || hasNoSignedComparisonUses (Node))) {
3076
+ // For example, "testq %rax, $268468232" to "testl %eax, $268468232".
3077
+ // NOTE: We only want to run that transform if N0 is 32 or 64 bits.
3078
+ // Otherwize, we find ourselves in a position where we have to do
3079
+ // promotion. If previous passes did not promote the and, we assume
3080
+ // they had a good reason not to and do not promote here.
3081
+ VT = MVT::i32;
3082
+ SubRegOp = X86::sub_32bit;
3083
+ Op = X86::TEST32ri;
3084
+ } else {
3085
+ // No eligible transformation was found.
3086
+ break ;
3074
3087
}
3075
3088
3076
- // For example, "testl %eax, $32776" to "testw %ax, $32776".
3077
- // NOTE: We only want to form TESTW instructions if optimizing for
3078
- // min size. Otherwise we only save one byte and possibly get a length
3079
- // changing prefix penalty in the decoders.
3080
- if (OptForMinSize && isUInt<16 >(Mask) && N0.getValueType () != MVT::i16 &&
3081
- (!(Mask & 0x8000 ) || hasNoSignedComparisonUses (Node))) {
3082
- SDValue Imm = CurDAG->getTargetConstant (Mask, dl, MVT::i16);
3083
- SDValue Reg = N0.getOperand (0 );
3084
-
3085
- // Extract the 16-bit subregister.
3086
- SDValue Subreg = CurDAG->getTargetExtractSubreg (X86::sub_16bit, dl,
3087
- MVT::i16, Reg);
3088
-
3089
- // Emit a testw.
3090
- SDNode *NewNode = CurDAG->getMachineNode (X86::TEST16ri, dl, MVT::i32,
3091
- Subreg, Imm);
3092
- // Replace SUB|CMP with TEST, since SUB has two outputs while TEST has
3093
- // one, do not call ReplaceAllUsesWith.
3094
- ReplaceUses (SDValue (Node, (Opcode == X86ISD::SUB ? 1 : 0 )),
3095
- SDValue (NewNode, 0 ));
3096
- CurDAG->RemoveDeadNode (Node);
3097
- return ;
3098
- }
3089
+ SDValue Imm = CurDAG->getTargetConstant (Mask, dl, VT);
3090
+ SDValue Reg = N0.getOperand (0 );
3099
3091
3100
- // For example, "testq %rax, $268468232" to "testl %eax, $268468232".
3101
- if (isUInt<32 >(Mask) && N0.getValueType () == MVT::i64 &&
3102
- (!(Mask & 0x80000000 ) || hasNoSignedComparisonUses (Node))) {
3103
- SDValue Imm = CurDAG->getTargetConstant (Mask, dl, MVT::i32);
3104
- SDValue Reg = N0.getOperand (0 );
3105
-
3106
- // Extract the 32-bit subregister.
3107
- SDValue Subreg = CurDAG->getTargetExtractSubreg (X86::sub_32bit, dl,
3108
- MVT::i32, Reg);
3109
- // Emit a testl.
3110
- SDNode *NewNode = CurDAG->getMachineNode (X86::TEST32ri, dl, MVT::i32,
3111
- Subreg, Imm);
3112
- // Replace SUB|CMP with TEST, since SUB has two outputs while TEST has
3113
- // one, do not call ReplaceAllUsesWith.
3114
- ReplaceUses (SDValue (Node, (Opcode == X86ISD::SUB ? 1 : 0 )),
3115
- SDValue (NewNode, 0 ));
3116
- CurDAG->RemoveDeadNode (Node);
3117
- return ;
3118
- }
3092
+ // Extract the subregister if necessary.
3093
+ if (N0.getValueType () != VT)
3094
+ Reg = CurDAG->getTargetExtractSubreg (SubRegOp, dl, VT, Reg);
3095
+
3096
+ // Emit a testl or testw.
3097
+ SDNode *NewNode = CurDAG->getMachineNode (Op, dl, MVT::i32, Reg, Imm);
3098
+ // Replace SUB|CMP with TEST, since SUB has two outputs while TEST has
3099
+ // one, do not call ReplaceAllUsesWith.
3100
+ ReplaceUses (SDValue (Node, (Opcode == X86ISD::SUB ? 1 : 0 )),
3101
+ SDValue (NewNode, 0 ));
3102
+ CurDAG->RemoveDeadNode (Node);
3103
+ return ;
3119
3104
}
3120
3105
break ;
3121
3106
}
0 commit comments