Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -6201,13 +6201,21 @@ } } - // sext(setcc x, y, cc) -> (select (setcc x, y, cc), -1, 0) + // sext(setcc x, y, cc) -> (select (setcc x, y, cc), T, 0) + // Here, T can be 1 or -1, depending on the type of the setcc and + // getBooleanContents(). unsigned ElementWidth = VT.getScalarType().getSizeInBits(); + unsigned SetCCWidth = N0.getValueType().getScalarType().getSizeInBits(); + SDLoc DL(N); - SDValue NegOne = - DAG.getConstant(APInt::getAllOnesValue(ElementWidth), DL, VT); + APInt TrueInt = + ((SetCCWidth != 1) && (TLI.getBooleanContents(VT) == + TargetLowering::ZeroOrOneBooleanContent)) + ? APInt(ElementWidth, 1) + : APInt::getAllOnesValue(ElementWidth); + SDValue TrueVal = DAG.getConstant(TrueInt, DL, VT); if (SDValue SCC = SimplifySelectCC( - DL, N0.getOperand(0), N0.getOperand(1), NegOne, + DL, N0.getOperand(0), N0.getOperand(1), TrueVal, DAG.getConstant(0, DL, VT), cast(N0.getOperand(2))->get(), true)) return SCC; @@ -6221,7 +6229,7 @@ SDValue SetCC = DAG.getSetCC(DL, SetCCVT, N0.getOperand(0), N0.getOperand(1), CC); return DAG.getSelect(DL, VT, SetCC, - NegOne, DAG.getConstant(0, DL, VT)); + TrueVal, DAG.getConstant(0, DL, VT)); } } } Index: test/CodeGen/X86/pr28504.ll =================================================================== --- test/CodeGen/X86/pr28504.ll +++ test/CodeGen/X86/pr28504.ll @@ -0,0 +1,45 @@ +; RUN: llc < %s | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK-LABEL: main: +; CHECK: movb $1, %al +; CHECK: xorl %ecx, %ecx +; CHECK: cmpb $1, %al +; CHECK: sete %cl +define i32 @main() { +bb: + %tmp1 = alloca i8, align 1 + %tmp2 = alloca i32, align 4 + %tmp3 = alloca i16, align 2 + store i8 1, i8* %tmp1, align 1 + %tmp4 = load i8, i8* %tmp1, align 1 + %tmp5 = sext i8 %tmp4 to i32 + %tmp6 = load i8, i8* %tmp1, align 1 + %tmp7 = zext i8 %tmp6 to i32 + %tmp8 = sub nsw i32 %tmp5, %tmp7 + %tmp9 = load i8, i8* %tmp1, align 1 + %tmp10 = sext i8 %tmp9 to i32 + %tmp11 = icmp eq i32 %tmp10, 1 + %tmp12 = zext i1 %tmp11 to i32 + %tmp13 = add nsw i32 %tmp8, %tmp12 + %tmp14 = trunc i32 %tmp13 to i8 + %tmp15 = sext i8 %tmp14 to i16 + %tmp16 = sext i16 %tmp15 to i32 + store i32 %tmp16, i32* %tmp2, align 4 + %tmp17 = load i8, i8* %tmp1, align 1 + %tmp18 = sext i8 %tmp17 to i16 + store i16 %tmp18, i16* %tmp3, align 2 + %tmp19 = load i32, i32* %tmp2, align 4 + %tmp20 = icmp ne i32 %tmp19, 1 + br i1 %tmp20, label %bb21, label %bb22 + +bb21: ; preds = %bb + call void @abort() + unreachable + +bb22: ; preds = %bb + ret i32 0 +} + +declare void @abort()