Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2095,6 +2095,7 @@ // the largest legal integer type. We need to be conservative here since // x86 generates redundant zero-extenstion instructions if the operand is // truncated to i8 or i16. + bool TruncCond = false; if (DL && BitWidth > NewWidth && NewWidth >= DL->getLargestLegalIntTypeSize()) { IntegerType *Ty = IntegerType::get(SI.getContext(), NewWidth); @@ -2105,6 +2106,7 @@ for (auto &C : SI.cases()) static_cast(&C)->setValue(ConstantInt::get( SI.getContext(), C.getCaseValue()->getValue().trunc(NewWidth))); + TruncCond = true; } if (Instruction *I = dyn_cast(Cond)) { @@ -2115,8 +2117,11 @@ for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) { ConstantInt* CaseVal = i.getCaseValue(); - Constant* NewCaseVal = ConstantExpr::getSub(cast(CaseVal), - AddRHS); + Constant *LHS = cast( + TruncCond ? ConstantInt::get(SI.getContext(), + CaseVal->getValue().sext(BitWidth)) + : CaseVal); + Constant* NewCaseVal = ConstantExpr::getSub(LHS, AddRHS); assert(isa(NewCaseVal) && "Result of expression should be constant"); i.setValue(cast(NewCaseVal)); Index: test/Transforms/InstCombine/narrow-switch.ll =================================================================== --- test/Transforms/InstCombine/narrow-switch.ll +++ test/Transforms/InstCombine/narrow-switch.ll @@ -91,3 +91,33 @@ %retval.0 = phi i32 [ 24, %sw.default ], [ 123, %sw.bb2 ], [ 213, %sw.bb1 ], [ 231, %entry ] ret i32 %retval.0 } + +; Make sure to avoid assertion crashes and use the type before +; truncation to generate the sub constant expressions that leads +; to the recomputed condition. +; +; CHECK-LABEL: @trunc64to59 +; CHECK: switch i59 +; CHECK: i59 0, label +; CHECK: i59 18717182647723699, label + +define void @trunc64to59(i64 %a) { +entry: + %tmp0 = and i64 %a, 15 + %tmp1 = mul i64 %tmp0, -6425668444178048401 + %tmp2 = add i64 %tmp1, 5170979678563097242 + %tmp3 = mul i64 %tmp2, 1627972535142754813 + switch i64 %tmp3, label %sw.default [ + i64 847514119312061490, label %sw.bb1 + i64 866231301959785189, label %sw.bb2 + ] + +sw.bb1: + br label %sw.default + +sw.bb2: + br label %sw.default + +sw.default: + ret void +}