Teach the DAGCombine to fold this pattern(c1 and c2 is constant).

// fold (sext (select cond, c1, c2)) -> (select cond, sext c1, sext c2)
// fold (zext (select cond, c1, c2)) -> (select cond, zext c1, zext c2)
// fold (aext (select cond, c1, c2)) -> (select cond, sext c1, sext c2)
Sign extend the operands if it is any_extend, to keep the signess of the operands that, the other combine rule would apply. The any_extend is handled as zero extend for constants. i.e.

t1: i8 = select t0, Constant:i8<-1>, Constant:i8<0>
t2: i64 = any_extend t1
 -->
t3: i64 = select t0, Constant:i64<-1>, Constant:i64<0>
 -->
t4: i64 = sign_extend_inreg t3

Differential Revision: https://reviews.llvm.org/D63318



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364382 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 0612348..3b48037 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -8902,6 +8902,7 @@
   unsigned Opcode = N->getOpcode();
   SDValue N0 = N->getOperand(0);
   EVT VT = N->getValueType(0);
+  SDLoc DL(N);
 
   assert((Opcode == ISD::SIGN_EXTEND || Opcode == ISD::ZERO_EXTEND ||
          Opcode == ISD::ANY_EXTEND || Opcode == ISD::SIGN_EXTEND_VECTOR_INREG ||
@@ -8912,7 +8913,33 @@
   // fold (zext c1) -> c1
   // fold (aext c1) -> c1
   if (isa<ConstantSDNode>(N0))
-    return DAG.getNode(Opcode, SDLoc(N), VT, N0);
+    return DAG.getNode(Opcode, DL, VT, N0);
+
+  // fold (sext (select cond, c1, c2)) -> (select cond, sext c1, sext c2)
+  // fold (zext (select cond, c1, c2)) -> (select cond, zext c1, zext c2)
+  // fold (aext (select cond, c1, c2)) -> (select cond, sext c1, sext c2)
+  if (N0->getOpcode() == ISD::SELECT) {
+    SDValue Op1 = N0->getOperand(1);
+    SDValue Op2 = N0->getOperand(2);
+    if (isa<ConstantSDNode>(Op1) && isa<ConstantSDNode>(Op2) &&
+        (Opcode != ISD::ZERO_EXTEND || !TLI.isZExtFree(N0.getValueType(), VT))) {
+      // For any_extend, choose sign extension of the constants to allow a
+      // possible further transform to sign_extend_inreg.i.e.
+      //
+      // t1: i8 = select t0, Constant:i8<-1>, Constant:i8<0>
+      // t2: i64 = any_extend t1
+      // -->
+      // t3: i64 = select t0, Constant:i64<-1>, Constant:i64<0>
+      // -->
+      // t4: i64 = sign_extend_inreg t3
+      unsigned FoldOpc = Opcode;
+      if (FoldOpc == ISD::ANY_EXTEND)
+        FoldOpc = ISD::SIGN_EXTEND;
+      return DAG.getSelect(DL, VT, N0->getOperand(0),
+                           DAG.getNode(FoldOpc, DL, VT, Op1),
+                           DAG.getNode(FoldOpc, DL, VT, Op2));
+    }
+  }
 
   // fold (sext (build_vector AllConstants) -> (build_vector AllConstants)
   // fold (zext (build_vector AllConstants) -> (build_vector AllConstants)
@@ -8927,7 +8954,6 @@
   unsigned EVTBits = N0->getValueType(0).getScalarSizeInBits();
   SmallVector<SDValue, 8> Elts;
   unsigned NumElts = VT.getVectorNumElements();
-  SDLoc DL(N);
 
   // For zero-extensions, UNDEF elements still guarantee to have the upper
   // bits set to zero.
diff --git a/test/CodeGen/PowerPC/bool-math.ll b/test/CodeGen/PowerPC/bool-math.ll
index 970ccd0..7b9c8c4 100644
--- a/test/CodeGen/PowerPC/bool-math.ll
+++ b/test/CodeGen/PowerPC/bool-math.ll
@@ -119,7 +119,7 @@
 define i8 @low_bit_select_constants_bigger_true_same_size_result(i8 %x) {
 ; CHECK-LABEL: low_bit_select_constants_bigger_true_same_size_result:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    rlwinm 3, 3, 0, 31, 31
+; CHECK-NEXT:    clrldi 3, 3, 63
 ; CHECK-NEXT:    subfic 3, 3, -29
 ; CHECK-NEXT:    blr
   %a = and i8 %x, 1
@@ -143,7 +143,7 @@
 define i8 @low_bit_select_constants_bigger_true_narrower_result(i16 %x) {
 ; CHECK-LABEL: low_bit_select_constants_bigger_true_narrower_result:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    rlwinm 3, 3, 0, 31, 31
+; CHECK-NEXT:    clrldi 3, 3, 63
 ; CHECK-NEXT:    subfic 3, 3, 41
 ; CHECK-NEXT:    blr
   %a = and i16 %x, 1
diff --git a/test/CodeGen/PowerPC/select_const.ll b/test/CodeGen/PowerPC/select_const.ll
index 461e0eb..d07d6d6 100644
--- a/test/CodeGen/PowerPC/select_const.ll
+++ b/test/CodeGen/PowerPC/select_const.ll
@@ -67,76 +67,31 @@
 ; select Cond, 0, -1 --> sext (!Cond)
 
 define i32 @select_0_or_neg1(i1 %cond) {
-; ISEL-LABEL: select_0_or_neg1:
-; ISEL:       # %bb.0:
-; ISEL-NEXT:    li 4, 0
-; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    oris 3, 4, 65535
-; ISEL-NEXT:    ori 3, 3, 65535
-; ISEL-NEXT:    isel 3, 0, 3, 1
-; ISEL-NEXT:    blr
-;
-; NO_ISEL-LABEL: select_0_or_neg1:
-; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    li 4, 0
-; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    oris 3, 4, 65535
-; NO_ISEL-NEXT:    ori 3, 3, 65535
-; NO_ISEL-NEXT:    bc 12, 1, .LBB6_1
-; NO_ISEL-NEXT:    blr
-; NO_ISEL-NEXT:  .LBB6_1:
-; NO_ISEL-NEXT:    addi 3, 0, 0
-; NO_ISEL-NEXT:    blr
+; ALL-LABEL: select_0_or_neg1:
+; ALL:       # %bb.0:
+; ALL-NEXT:    not 3, 3
+; ALL-NEXT:    clrldi 3, 3, 63
+; ALL-NEXT:    neg 3, 3
+; ALL-NEXT:    blr
   %sel = select i1 %cond, i32 0, i32 -1
   ret i32 %sel
 }
 
 define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) {
-; ISEL-LABEL: select_0_or_neg1_zeroext:
-; ISEL:       # %bb.0:
-; ISEL-NEXT:    li 4, 0
-; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    oris 3, 4, 65535
-; ISEL-NEXT:    ori 3, 3, 65535
-; ISEL-NEXT:    isel 3, 0, 3, 1
-; ISEL-NEXT:    blr
-;
-; NO_ISEL-LABEL: select_0_or_neg1_zeroext:
-; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    li 4, 0
-; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    oris 3, 4, 65535
-; NO_ISEL-NEXT:    ori 3, 3, 65535
-; NO_ISEL-NEXT:    bc 12, 1, .LBB7_1
-; NO_ISEL-NEXT:    blr
-; NO_ISEL-NEXT:  .LBB7_1:
-; NO_ISEL-NEXT:    addi 3, 0, 0
-; NO_ISEL-NEXT:    blr
+; ALL-LABEL: select_0_or_neg1_zeroext:
+; ALL:       # %bb.0:
+; ALL-NEXT:    xori 3, 3, 1
+; ALL-NEXT:    neg 3, 3
+; ALL-NEXT:    blr
   %sel = select i1 %cond, i32 0, i32 -1
   ret i32 %sel
 }
 
 define i32 @select_0_or_neg1_signext(i1 signext %cond) {
-; ISEL-LABEL: select_0_or_neg1_signext:
-; ISEL:       # %bb.0:
-; ISEL-NEXT:    li 4, 0
-; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    oris 3, 4, 65535
-; ISEL-NEXT:    ori 3, 3, 65535
-; ISEL-NEXT:    isel 3, 0, 3, 1
-; ISEL-NEXT:    blr
-;
-; NO_ISEL-LABEL: select_0_or_neg1_signext:
-; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    li 4, 0
-; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    oris 3, 4, 65535
-; NO_ISEL-NEXT:    ori 3, 3, 65535
-; NO_ISEL-NEXT:    bc 12, 1, .LBB8_1
-; NO_ISEL-NEXT:    blr
-; NO_ISEL-NEXT:  .LBB8_1:
-; NO_ISEL-NEXT:    addi 3, 0, 0
-; NO_ISEL-NEXT:    blr
+; ALL-LABEL: select_0_or_neg1_signext:
+; ALL:       # %bb.0:
+; ALL-NEXT:    not 3, 3
+; ALL-NEXT:    blr
   %sel = select i1 %cond, i32 0, i32 -1
   ret i32 %sel
 }
@@ -144,73 +99,28 @@
 ; select Cond, -1, 0 --> sext (Cond)
 
 define i32 @select_neg1_or_0(i1 %cond) {
-; ISEL-LABEL: select_neg1_or_0:
-; ISEL:       # %bb.0:
-; ISEL-NEXT:    li 4, 0
-; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    oris 3, 4, 65535
-; ISEL-NEXT:    ori 3, 3, 65535
-; ISEL-NEXT:    isel 3, 3, 4, 1
-; ISEL-NEXT:    blr
-;
-; NO_ISEL-LABEL: select_neg1_or_0:
-; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    li 4, 0
-; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    oris 3, 4, 65535
-; NO_ISEL-NEXT:    ori 3, 3, 65535
-; NO_ISEL-NEXT:    bclr 12, 1, 0
-; NO_ISEL-NEXT:  # %bb.1:
-; NO_ISEL-NEXT:    ori 3, 4, 0
-; NO_ISEL-NEXT:    blr
+; ALL-LABEL: select_neg1_or_0:
+; ALL:       # %bb.0:
+; ALL-NEXT:    clrldi 3, 3, 63
+; ALL-NEXT:    neg 3, 3
+; ALL-NEXT:    blr
   %sel = select i1 %cond, i32 -1, i32 0
   ret i32 %sel
 }
 
 define i32 @select_neg1_or_0_zeroext(i1 zeroext %cond) {
-; ISEL-LABEL: select_neg1_or_0_zeroext:
-; ISEL:       # %bb.0:
-; ISEL-NEXT:    li 4, 0
-; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    oris 3, 4, 65535
-; ISEL-NEXT:    ori 3, 3, 65535
-; ISEL-NEXT:    isel 3, 3, 4, 1
-; ISEL-NEXT:    blr
-;
-; NO_ISEL-LABEL: select_neg1_or_0_zeroext:
-; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    li 4, 0
-; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    oris 3, 4, 65535
-; NO_ISEL-NEXT:    ori 3, 3, 65535
-; NO_ISEL-NEXT:    bclr 12, 1, 0
-; NO_ISEL-NEXT:  # %bb.1:
-; NO_ISEL-NEXT:    ori 3, 4, 0
-; NO_ISEL-NEXT:    blr
+; ALL-LABEL: select_neg1_or_0_zeroext:
+; ALL:       # %bb.0:
+; ALL-NEXT:    neg 3, 3
+; ALL-NEXT:    blr
   %sel = select i1 %cond, i32 -1, i32 0
   ret i32 %sel
 }
 
 define i32 @select_neg1_or_0_signext(i1 signext %cond) {
-; ISEL-LABEL: select_neg1_or_0_signext:
-; ISEL:       # %bb.0:
-; ISEL-NEXT:    li 4, 0
-; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    oris 3, 4, 65535
-; ISEL-NEXT:    ori 3, 3, 65535
-; ISEL-NEXT:    isel 3, 3, 4, 1
-; ISEL-NEXT:    blr
-;
-; NO_ISEL-LABEL: select_neg1_or_0_signext:
-; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    li 4, 0
-; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    oris 3, 4, 65535
-; NO_ISEL-NEXT:    ori 3, 3, 65535
-; NO_ISEL-NEXT:    bclr 12, 1, 0
-; NO_ISEL-NEXT:  # %bb.1:
-; NO_ISEL-NEXT:    ori 3, 4, 0
-; NO_ISEL-NEXT:    blr
+; ALL-LABEL: select_neg1_or_0_signext:
+; ALL:       # %bb.0:
+; ALL-NEXT:    blr
   %sel = select i1 %cond, i32 -1, i32 0
   ret i32 %sel
 }
@@ -376,24 +286,21 @@
 define i8 @sel_constants_sub_constant(i1 %cond) {
 ; ISEL-LABEL: sel_constants_sub_constant:
 ; ISEL:       # %bb.0:
-; ISEL-NEXT:    li 4, 0
 ; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    oris 3, 4, 65535
-; ISEL-NEXT:    li 4, 18
-; ISEL-NEXT:    ori 3, 3, 65527
-; ISEL-NEXT:    isel 3, 3, 4, 1
+; ISEL-NEXT:    li 4, -9
+; ISEL-NEXT:    li 3, 18
+; ISEL-NEXT:    isel 3, 4, 3, 1
 ; ISEL-NEXT:    blr
 ;
 ; NO_ISEL-LABEL: sel_constants_sub_constant:
 ; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    li 4, 0
 ; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    oris 3, 4, 65535
-; NO_ISEL-NEXT:    li 4, 18
-; NO_ISEL-NEXT:    ori 3, 3, 65527
-; NO_ISEL-NEXT:    bclr 12, 1, 0
-; NO_ISEL-NEXT:  # %bb.1:
-; NO_ISEL-NEXT:    ori 3, 4, 0
+; NO_ISEL-NEXT:    li 4, -9
+; NO_ISEL-NEXT:    li 3, 18
+; NO_ISEL-NEXT:    bc 12, 1, .LBB22_1
+; NO_ISEL-NEXT:    blr
+; NO_ISEL-NEXT:  .LBB22_1:
+; NO_ISEL-NEXT:    addi 3, 4, 0
 ; NO_ISEL-NEXT:    blr
   %sel = select i1 %cond, i8 -4, i8 23
   %bo = sub i8 %sel, 5
@@ -427,24 +334,21 @@
 define i8 @sel_constants_mul_constant(i1 %cond) {
 ; ISEL-LABEL: sel_constants_mul_constant:
 ; ISEL:       # %bb.0:
-; ISEL-NEXT:    lis 4, 16383
 ; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    ori 3, 4, 65531
-; ISEL-NEXT:    li 4, 115
-; ISEL-NEXT:    sldi 3, 3, 2
-; ISEL-NEXT:    isel 3, 3, 4, 1
+; ISEL-NEXT:    li 4, -20
+; ISEL-NEXT:    li 3, 115
+; ISEL-NEXT:    isel 3, 4, 3, 1
 ; ISEL-NEXT:    blr
 ;
 ; NO_ISEL-LABEL: sel_constants_mul_constant:
 ; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    lis 4, 16383
 ; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    ori 3, 4, 65531
-; NO_ISEL-NEXT:    li 4, 115
-; NO_ISEL-NEXT:    sldi 3, 3, 2
-; NO_ISEL-NEXT:    bclr 12, 1, 0
-; NO_ISEL-NEXT:  # %bb.1:
-; NO_ISEL-NEXT:    ori 3, 4, 0
+; NO_ISEL-NEXT:    li 4, -20
+; NO_ISEL-NEXT:    li 3, 115
+; NO_ISEL-NEXT:    bc 12, 1, .LBB24_1
+; NO_ISEL-NEXT:    blr
+; NO_ISEL-NEXT:  .LBB24_1:
+; NO_ISEL-NEXT:    addi 3, 4, 0
 ; NO_ISEL-NEXT:    blr
   %sel = select i1 %cond, i8 -4, i8 23
   %bo = mul i8 %sel, 5
@@ -544,24 +448,21 @@
 define i8 @sel_constants_srem_constant(i1 %cond) {
 ; ISEL-LABEL: sel_constants_srem_constant:
 ; ISEL:       # %bb.0:
-; ISEL-NEXT:    lis 4, 16383
 ; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    ori 3, 4, 65535
-; ISEL-NEXT:    li 4, 3
-; ISEL-NEXT:    sldi 3, 3, 2
-; ISEL-NEXT:    isel 3, 3, 4, 1
+; ISEL-NEXT:    li 4, -4
+; ISEL-NEXT:    li 3, 3
+; ISEL-NEXT:    isel 3, 4, 3, 1
 ; ISEL-NEXT:    blr
 ;
 ; NO_ISEL-LABEL: sel_constants_srem_constant:
 ; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    lis 4, 16383
 ; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    ori 3, 4, 65535
-; NO_ISEL-NEXT:    li 4, 3
-; NO_ISEL-NEXT:    sldi 3, 3, 2
-; NO_ISEL-NEXT:    bclr 12, 1, 0
-; NO_ISEL-NEXT:  # %bb.1:
-; NO_ISEL-NEXT:    ori 3, 4, 0
+; NO_ISEL-NEXT:    li 4, -4
+; NO_ISEL-NEXT:    li 3, 3
+; NO_ISEL-NEXT:    bc 12, 1, .LBB29_1
+; NO_ISEL-NEXT:    blr
+; NO_ISEL-NEXT:  .LBB29_1:
+; NO_ISEL-NEXT:    addi 3, 4, 0
 ; NO_ISEL-NEXT:    blr
   %sel = select i1 %cond, i8 -4, i8 23
   %bo = srem i8 %sel, 5
@@ -595,7 +496,7 @@
 define i8 @sel_constants_urem_constant(i1 %cond) {
 ; ALL-LABEL: sel_constants_urem_constant:
 ; ALL:       # %bb.0:
-; ALL-NEXT:    rlwinm 3, 3, 0, 31, 31
+; ALL-NEXT:    clrldi 3, 3, 63
 ; ALL-NEXT:    subfic 3, 3, 3
 ; ALL-NEXT:    blr
   %sel = select i1 %cond, i8 -4, i8 23
@@ -630,7 +531,7 @@
 define i8 @sel_constants_and_constant(i1 %cond) {
 ; ALL-LABEL: sel_constants_and_constant:
 ; ALL:       # %bb.0:
-; ALL-NEXT:    rlwinm 3, 3, 0, 31, 31
+; ALL-NEXT:    clrldi 3, 3, 63
 ; ALL-NEXT:    subfic 3, 3, 5
 ; ALL-NEXT:    blr
   %sel = select i1 %cond, i8 -4, i8 23
@@ -641,24 +542,21 @@
 define i8 @sel_constants_or_constant(i1 %cond) {
 ; ISEL-LABEL: sel_constants_or_constant:
 ; ISEL:       # %bb.0:
-; ISEL-NEXT:    li 4, 0
 ; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    oris 3, 4, 65535
-; ISEL-NEXT:    li 4, 23
-; ISEL-NEXT:    ori 3, 3, 65533
-; ISEL-NEXT:    isel 3, 3, 4, 1
+; ISEL-NEXT:    li 4, -3
+; ISEL-NEXT:    li 3, 23
+; ISEL-NEXT:    isel 3, 4, 3, 1
 ; ISEL-NEXT:    blr
 ;
 ; NO_ISEL-LABEL: sel_constants_or_constant:
 ; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    li 4, 0
 ; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    oris 3, 4, 65535
-; NO_ISEL-NEXT:    li 4, 23
-; NO_ISEL-NEXT:    ori 3, 3, 65533
-; NO_ISEL-NEXT:    bclr 12, 1, 0
-; NO_ISEL-NEXT:  # %bb.1:
-; NO_ISEL-NEXT:    ori 3, 4, 0
+; NO_ISEL-NEXT:    li 4, -3
+; NO_ISEL-NEXT:    li 3, 23
+; NO_ISEL-NEXT:    bc 12, 1, .LBB34_1
+; NO_ISEL-NEXT:    blr
+; NO_ISEL-NEXT:  .LBB34_1:
+; NO_ISEL-NEXT:    addi 3, 4, 0
 ; NO_ISEL-NEXT:    blr
   %sel = select i1 %cond, i8 -4, i8 23
   %bo = or i8 %sel, 5
@@ -668,24 +566,21 @@
 define i8 @sel_constants_xor_constant(i1 %cond) {
 ; ISEL-LABEL: sel_constants_xor_constant:
 ; ISEL:       # %bb.0:
-; ISEL-NEXT:    li 4, 0
 ; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    oris 3, 4, 65535
-; ISEL-NEXT:    li 4, 18
-; ISEL-NEXT:    ori 3, 3, 65529
-; ISEL-NEXT:    isel 3, 3, 4, 1
+; ISEL-NEXT:    li 4, -7
+; ISEL-NEXT:    li 3, 18
+; ISEL-NEXT:    isel 3, 4, 3, 1
 ; ISEL-NEXT:    blr
 ;
 ; NO_ISEL-LABEL: sel_constants_xor_constant:
 ; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    li 4, 0
 ; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    oris 3, 4, 65535
-; NO_ISEL-NEXT:    li 4, 18
-; NO_ISEL-NEXT:    ori 3, 3, 65529
-; NO_ISEL-NEXT:    bclr 12, 1, 0
-; NO_ISEL-NEXT:  # %bb.1:
-; NO_ISEL-NEXT:    ori 3, 4, 0
+; NO_ISEL-NEXT:    li 4, -7
+; NO_ISEL-NEXT:    li 3, 18
+; NO_ISEL-NEXT:    bc 12, 1, .LBB35_1
+; NO_ISEL-NEXT:    blr
+; NO_ISEL-NEXT:  .LBB35_1:
+; NO_ISEL-NEXT:    addi 3, 4, 0
 ; NO_ISEL-NEXT:    blr
   %sel = select i1 %cond, i8 -4, i8 23
   %bo = xor i8 %sel, 5
@@ -695,25 +590,17 @@
 define i8 @sel_constants_shl_constant(i1 %cond) {
 ; ISEL-LABEL: sel_constants_shl_constant:
 ; ISEL:       # %bb.0:
-; ISEL-NEXT:    lis 4, 2047
-; ISEL-NEXT:    lis 5, 511
 ; ISEL-NEXT:    andi. 3, 3, 1
-; ISEL-NEXT:    ori 3, 4, 65535
-; ISEL-NEXT:    ori 4, 5, 65535
-; ISEL-NEXT:    sldi 3, 3, 5
-; ISEL-NEXT:    sldi 4, 4, 7
+; ISEL-NEXT:    li 4, -128
+; ISEL-NEXT:    li 3, -32
 ; ISEL-NEXT:    isel 3, 4, 3, 1
 ; ISEL-NEXT:    blr
 ;
 ; NO_ISEL-LABEL: sel_constants_shl_constant:
 ; NO_ISEL:       # %bb.0:
-; NO_ISEL-NEXT:    lis 4, 2047
-; NO_ISEL-NEXT:    lis 5, 511
 ; NO_ISEL-NEXT:    andi. 3, 3, 1
-; NO_ISEL-NEXT:    ori 3, 4, 65535
-; NO_ISEL-NEXT:    ori 4, 5, 65535
-; NO_ISEL-NEXT:    sldi 3, 3, 5
-; NO_ISEL-NEXT:    sldi 4, 4, 7
+; NO_ISEL-NEXT:    li 4, -128
+; NO_ISEL-NEXT:    li 3, -32
 ; NO_ISEL-NEXT:    bc 12, 1, .LBB36_1
 ; NO_ISEL-NEXT:    blr
 ; NO_ISEL-NEXT:  .LBB36_1:
diff --git a/test/CodeGen/X86/avx512-insert-extract.ll b/test/CodeGen/X86/avx512-insert-extract.ll
index 02c67ba..20db662 100644
--- a/test/CodeGen/X86/avx512-insert-extract.ll
+++ b/test/CodeGen/X86/avx512-insert-extract.ll
@@ -908,22 +908,20 @@
 ; KNL-NEXT:    ## kill: def $xmm1 killed $xmm1 def $zmm1
 ; KNL-NEXT:    ## kill: def $xmm0 killed $xmm0 def $zmm0
 ; KNL-NEXT:    vpcmpnleuq %zmm1, %zmm0, %k0
-; KNL-NEXT:    kmovw %k0, %eax
-; KNL-NEXT:    andb $1, %al
-; KNL-NEXT:    movb $4, %cl
-; KNL-NEXT:    subb %al, %cl
-; KNL-NEXT:    movzbl %cl, %eax
+; KNL-NEXT:    kmovw %k0, %ecx
+; KNL-NEXT:    andl $1, %ecx
+; KNL-NEXT:    movl $4, %eax
+; KNL-NEXT:    subl %ecx, %eax
 ; KNL-NEXT:    vzeroupper
 ; KNL-NEXT:    retq
 ;
 ; SKX-LABEL: test_extractelement_v2i1:
 ; SKX:       ## %bb.0:
 ; SKX-NEXT:    vpcmpnleuq %xmm1, %xmm0, %k0
-; SKX-NEXT:    kmovd %k0, %eax
-; SKX-NEXT:    andb $1, %al
-; SKX-NEXT:    movb $4, %cl
-; SKX-NEXT:    subb %al, %cl
-; SKX-NEXT:    movzbl %cl, %eax
+; SKX-NEXT:    kmovd %k0, %ecx
+; SKX-NEXT:    andl $1, %ecx
+; SKX-NEXT:    movl $4, %eax
+; SKX-NEXT:    subl %ecx, %eax
 ; SKX-NEXT:    retq
   %t1 = icmp ugt <2 x i64> %a, %b
   %t2 = extractelement <2 x i1> %t1, i32 0
@@ -1024,11 +1022,10 @@
 ; KNL-NEXT:    vpmovsxbd %xmm0, %zmm0
 ; KNL-NEXT:    vptestmd %zmm0, %zmm0, %k0
 ; KNL-NEXT:    kshiftrw $15, %k0, %k0
-; KNL-NEXT:    kmovw %k0, %eax
-; KNL-NEXT:    andb $1, %al
-; KNL-NEXT:    movb $4, %cl
-; KNL-NEXT:    subb %al, %cl
-; KNL-NEXT:    movzbl %cl, %eax
+; KNL-NEXT:    kmovw %k0, %ecx
+; KNL-NEXT:    andl $1, %ecx
+; KNL-NEXT:    movl $4, %eax
+; KNL-NEXT:    subl %ecx, %eax
 ; KNL-NEXT:    vzeroupper
 ; KNL-NEXT:    retq
 ;
@@ -1036,11 +1033,10 @@
 ; SKX:       ## %bb.0:
 ; SKX-NEXT:    vpcmpnleub %zmm1, %zmm0, %k0
 ; SKX-NEXT:    kshiftrq $63, %k0, %k0
-; SKX-NEXT:    kmovd %k0, %eax
-; SKX-NEXT:    andb $1, %al
-; SKX-NEXT:    movb $4, %cl
-; SKX-NEXT:    subb %al, %cl
-; SKX-NEXT:    movzbl %cl, %eax
+; SKX-NEXT:    kmovd %k0, %ecx
+; SKX-NEXT:    andl $1, %ecx
+; SKX-NEXT:    movl $4, %eax
+; SKX-NEXT:    subl %ecx, %eax
 ; SKX-NEXT:    vzeroupper
 ; SKX-NEXT:    retq
   %t1 = icmp ugt <64 x i8> %a, %b
diff --git a/test/CodeGen/X86/cmov-promotion.ll b/test/CodeGen/X86/cmov-promotion.ll
index bcb0c59..12fb512 100644
--- a/test/CodeGen/X86/cmov-promotion.ll
+++ b/test/CodeGen/X86/cmov-promotion.ll
@@ -15,12 +15,11 @@
 ; NO_CMOV-LABEL: cmov_zpromotion_8_to_16:
 ; NO_CMOV:       # %bb.0:
 ; NO_CMOV-NEXT:    testb $1, {{[0-9]+}}(%esp)
-; NO_CMOV-NEXT:    movb $117, %al
+; NO_CMOV-NEXT:    movl $117, %eax
 ; NO_CMOV-NEXT:    jne .LBB0_2
 ; NO_CMOV-NEXT:  # %bb.1:
-; NO_CMOV-NEXT:    movb $-19, %al
+; NO_CMOV-NEXT:    movl $237, %eax
 ; NO_CMOV-NEXT:  .LBB0_2:
-; NO_CMOV-NEXT:    movzbl %al, %eax
 ; NO_CMOV-NEXT:    # kill: def $ax killed $ax killed $eax
 ; NO_CMOV-NEXT:    retl
   %t0 = select i1 %c, i8 117, i8 -19
@@ -40,12 +39,11 @@
 ; NO_CMOV-LABEL: cmov_zpromotion_8_to_32:
 ; NO_CMOV:       # %bb.0:
 ; NO_CMOV-NEXT:    testb $1, {{[0-9]+}}(%esp)
-; NO_CMOV-NEXT:    movb $126, %al
+; NO_CMOV-NEXT:    movl $126, %eax
 ; NO_CMOV-NEXT:    jne .LBB1_2
 ; NO_CMOV-NEXT:  # %bb.1:
-; NO_CMOV-NEXT:    movb $-1, %al
+; NO_CMOV-NEXT:    movl $255, %eax
 ; NO_CMOV-NEXT:  .LBB1_2:
-; NO_CMOV-NEXT:    movzbl %al, %eax
 ; NO_CMOV-NEXT:    retl
   %t0 = select i1 %c, i8 12414, i8 -1
   %ret = zext i8 %t0 to i32
@@ -58,18 +56,17 @@
 ; CMOV-NEXT:    testb $1, %dil
 ; CMOV-NEXT:    movl $126, %ecx
 ; CMOV-NEXT:    movl $255, %eax
-; CMOV-NEXT:    cmovnel %ecx, %eax
+; CMOV-NEXT:    cmovneq %rcx, %rax
 ; CMOV-NEXT:    retq
 ;
 ; NO_CMOV-LABEL: cmov_zpromotion_8_to_64:
 ; NO_CMOV:       # %bb.0:
 ; NO_CMOV-NEXT:    testb $1, {{[0-9]+}}(%esp)
-; NO_CMOV-NEXT:    movb $126, %al
+; NO_CMOV-NEXT:    movl $126, %eax
 ; NO_CMOV-NEXT:    jne .LBB2_2
 ; NO_CMOV-NEXT:  # %bb.1:
-; NO_CMOV-NEXT:    movb $-1, %al
+; NO_CMOV-NEXT:    movl $255, %eax
 ; NO_CMOV-NEXT:  .LBB2_2:
-; NO_CMOV-NEXT:    movzbl %al, %eax
 ; NO_CMOV-NEXT:    xorl %edx, %edx
 ; NO_CMOV-NEXT:    retl
   %t0 = select i1 %c, i8 12414, i8 -1
@@ -106,7 +103,7 @@
 ; CMOV-NEXT:    testb $1, %dil
 ; CMOV-NEXT:    movl $12414, %ecx # imm = 0x307E
 ; CMOV-NEXT:    movl $65535, %eax # imm = 0xFFFF
-; CMOV-NEXT:    cmovnel %ecx, %eax
+; CMOV-NEXT:    cmovneq %rcx, %rax
 ; CMOV-NEXT:    retq
 ;
 ; NO_CMOV-LABEL: cmov_zpromotion_16_to_64:
@@ -161,12 +158,11 @@
 ; NO_CMOV-LABEL: cmov_spromotion_8_to_16:
 ; NO_CMOV:       # %bb.0:
 ; NO_CMOV-NEXT:    testb $1, {{[0-9]+}}(%esp)
-; NO_CMOV-NEXT:    movb $117, %al
+; NO_CMOV-NEXT:    movl $117, %eax
 ; NO_CMOV-NEXT:    jne .LBB6_2
 ; NO_CMOV-NEXT:  # %bb.1:
-; NO_CMOV-NEXT:    movb $-19, %al
+; NO_CMOV-NEXT:    movl $65517, %eax # imm = 0xFFED
 ; NO_CMOV-NEXT:  .LBB6_2:
-; NO_CMOV-NEXT:    movsbl %al, %eax
 ; NO_CMOV-NEXT:    # kill: def $ax killed $ax killed $eax
 ; NO_CMOV-NEXT:    retl
   %t0 = select i1 %c, i8 117, i8 -19
@@ -186,12 +182,11 @@
 ; NO_CMOV-LABEL: cmov_spromotion_8_to_32:
 ; NO_CMOV:       # %bb.0:
 ; NO_CMOV-NEXT:    testb $1, {{[0-9]+}}(%esp)
-; NO_CMOV-NEXT:    movb $126, %al
+; NO_CMOV-NEXT:    movl $126, %eax
 ; NO_CMOV-NEXT:    jne .LBB7_2
 ; NO_CMOV-NEXT:  # %bb.1:
-; NO_CMOV-NEXT:    movb $-1, %al
+; NO_CMOV-NEXT:    movl $-1, %eax
 ; NO_CMOV-NEXT:  .LBB7_2:
-; NO_CMOV-NEXT:    movsbl %al, %eax
 ; NO_CMOV-NEXT:    retl
   %t0 = select i1 %c, i8 12414, i8 -1
   %ret = sext i8 %t0 to i32
@@ -210,14 +205,14 @@
 ; NO_CMOV-LABEL: cmov_spromotion_8_to_64:
 ; NO_CMOV:       # %bb.0:
 ; NO_CMOV-NEXT:    testb $1, {{[0-9]+}}(%esp)
-; NO_CMOV-NEXT:    movb $126, %al
-; NO_CMOV-NEXT:    jne .LBB8_2
-; NO_CMOV-NEXT:  # %bb.1:
-; NO_CMOV-NEXT:    movb $-1, %al
-; NO_CMOV-NEXT:  .LBB8_2:
-; NO_CMOV-NEXT:    movsbl %al, %eax
-; NO_CMOV-NEXT:    movl %eax, %edx
-; NO_CMOV-NEXT:    sarl $31, %edx
+; NO_CMOV-NEXT:    jne .LBB8_1
+; NO_CMOV-NEXT:  # %bb.2:
+; NO_CMOV-NEXT:    movl $-1, %eax
+; NO_CMOV-NEXT:    movl $-1, %edx
+; NO_CMOV-NEXT:    retl
+; NO_CMOV-NEXT:  .LBB8_1:
+; NO_CMOV-NEXT:    xorl %edx, %edx
+; NO_CMOV-NEXT:    movl $126, %eax
 ; NO_CMOV-NEXT:    retl
   %t0 = select i1 %c, i8 12414, i8 -1
   %ret = sext i8 %t0 to i64
@@ -259,13 +254,14 @@
 ; NO_CMOV-LABEL: cmov_spromotion_16_to_64:
 ; NO_CMOV:       # %bb.0:
 ; NO_CMOV-NEXT:    testb $1, {{[0-9]+}}(%esp)
-; NO_CMOV-NEXT:    movl $12414, %eax # imm = 0x307E
-; NO_CMOV-NEXT:    jne .LBB10_2
-; NO_CMOV-NEXT:  # %bb.1:
+; NO_CMOV-NEXT:    jne .LBB10_1
+; NO_CMOV-NEXT:  # %bb.2:
 ; NO_CMOV-NEXT:    movl $-1, %eax
-; NO_CMOV-NEXT:  .LBB10_2:
-; NO_CMOV-NEXT:    movl %eax, %edx
-; NO_CMOV-NEXT:    sarl $31, %edx
+; NO_CMOV-NEXT:    movl $-1, %edx
+; NO_CMOV-NEXT:    retl
+; NO_CMOV-NEXT:  .LBB10_1:
+; NO_CMOV-NEXT:    xorl %edx, %edx
+; NO_CMOV-NEXT:    movl $12414, %eax # imm = 0x307E
 ; NO_CMOV-NEXT:    retl
   %t0 = select i1 %c, i16 12414, i16 -1
   %ret = sext i16 %t0 to i64
@@ -284,13 +280,14 @@
 ; NO_CMOV-LABEL: cmov_spromotion_32_to_64:
 ; NO_CMOV:       # %bb.0:
 ; NO_CMOV-NEXT:    testb $1, {{[0-9]+}}(%esp)
-; NO_CMOV-NEXT:    movl $12414, %eax # imm = 0x307E
-; NO_CMOV-NEXT:    jne .LBB11_2
-; NO_CMOV-NEXT:  # %bb.1:
+; NO_CMOV-NEXT:    jne .LBB11_1
+; NO_CMOV-NEXT:  # %bb.2:
 ; NO_CMOV-NEXT:    movl $-1, %eax
-; NO_CMOV-NEXT:  .LBB11_2:
-; NO_CMOV-NEXT:    movl %eax, %edx
-; NO_CMOV-NEXT:    sarl $31, %edx
+; NO_CMOV-NEXT:    movl $-1, %edx
+; NO_CMOV-NEXT:    retl
+; NO_CMOV-NEXT:  .LBB11_1:
+; NO_CMOV-NEXT:    xorl %edx, %edx
+; NO_CMOV-NEXT:    movl $12414, %eax # imm = 0x307E
 ; NO_CMOV-NEXT:    retl
   %t0 = select i1 %c, i32 12414, i32 -1
   %ret = sext i32 %t0 to i64
diff --git a/test/CodeGen/X86/select.ll b/test/CodeGen/X86/select.ll
index 11c531f..d174951 100644
--- a/test/CodeGen/X86/select.ll
+++ b/test/CodeGen/X86/select.ll
@@ -55,9 +55,8 @@
 ; GENERIC-NEXT:    callq _return_false
 ; GENERIC-NEXT:    xorl %ecx, %ecx
 ; GENERIC-NEXT:    testb $1, %al
-; GENERIC-NEXT:    movl $-480, %eax ## imm = 0xFE20
+; GENERIC-NEXT:    movl $-3840, %eax ## imm = 0xF100
 ; GENERIC-NEXT:    cmovnel %ecx, %eax
-; GENERIC-NEXT:    shll $3, %eax
 ; GENERIC-NEXT:    cmpl $32768, %eax ## imm = 0x8000
 ; GENERIC-NEXT:    jge LBB1_1
 ; GENERIC-NEXT:  ## %bb.2: ## %bb91
@@ -72,10 +71,9 @@
 ; ATOM-NEXT:    pushq %rax
 ; ATOM-NEXT:    callq _return_false
 ; ATOM-NEXT:    xorl %ecx, %ecx
-; ATOM-NEXT:    movl $-480, %edx ## imm = 0xFE20
+; ATOM-NEXT:    movl $-3840, %edx ## imm = 0xF100
 ; ATOM-NEXT:    testb $1, %al
 ; ATOM-NEXT:    cmovnel %ecx, %edx
-; ATOM-NEXT:    shll $3, %edx
 ; ATOM-NEXT:    cmpl $32768, %edx ## imm = 0x8000
 ; ATOM-NEXT:    jge LBB1_1
 ; ATOM-NEXT:  ## %bb.2: ## %bb91
@@ -91,9 +89,8 @@
 ; ATHLON-NEXT:    calll _return_false
 ; ATHLON-NEXT:    xorl %ecx, %ecx
 ; ATHLON-NEXT:    testb $1, %al
-; ATHLON-NEXT:    movl $-480, %eax ## imm = 0xFE20
+; ATHLON-NEXT:    movl $-3840, %eax ## imm = 0xF100
 ; ATHLON-NEXT:    cmovnel %ecx, %eax
-; ATHLON-NEXT:    shll $3, %eax
 ; ATHLON-NEXT:    cmpl $32768, %eax ## imm = 0x8000
 ; ATHLON-NEXT:    jge LBB1_1
 ; ATHLON-NEXT:  ## %bb.2: ## %bb91
@@ -110,9 +107,8 @@
 ; MCU-NEXT:    testb $1, %al
 ; MCU-NEXT:    jne .LBB1_2
 ; MCU-NEXT:  # %bb.1: # %entry
-; MCU-NEXT:    movl $-480, %ecx # imm = 0xFE20
+; MCU-NEXT:    movl $-3840, %ecx # imm = 0xF100
 ; MCU-NEXT:  .LBB1_2: # %entry
-; MCU-NEXT:    shll $3, %ecx
 ; MCU-NEXT:    cmpl $32768, %ecx # imm = 0x8000
 ; MCU-NEXT:    jge .LBB1_3
 ; MCU-NEXT:  # %bb.4: # %bb91