Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1890,12 +1890,13 @@ return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC)); } if (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE) { - // This is the same code as the SGT case, but assert the pre-condition - // that is needed for this to work with equality predicates. - assert(C.ashr(*ShiftAmt).shl(*ShiftAmt) == C && - "Compare known true or false was not folded"); - APInt ShiftedC = C.ashr(*ShiftAmt); - return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC)); + // This is the same transform as SGT, but we have to avoid the case where + // InstSimplify has not removed this compare because the shift is known to + // create poison (PR34838). + if (C.ashr(*ShiftAmt).shl(*ShiftAmt) == C) { + APInt ShiftedC = C.ashr(*ShiftAmt); + return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC)); + } } if (Pred == ICmpInst::ICMP_SLT) { // SLE is the same as above, but SLE is canonicalized to SLT, so convert: Index: test/Transforms/InstCombine/icmp-shl-nsw.ll =================================================================== --- test/Transforms/InstCombine/icmp-shl-nsw.ll +++ test/Transforms/InstCombine/icmp-shl-nsw.ll @@ -354,3 +354,24 @@ ret i1 %cmp } +; https://bugs.llvm.org/show_bug.cgi?id=34838 - the cmp is known true, but +; the shift is known to create poison, so InstSimplify doesn't kill the cmp. +; Thus, InstCombine can't assert that the cmp shouldn't exist. + +define i1 @PR34838(i8 %x) { +; CHECK-LABEL: @PR34838( +; CHECK-NEXT: [[ZX:%.*]] = zext i8 %x to i16 +; CHECK-NEXT: [[XOR:%.*]] = xor i16 [[ZX]], 511 +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i16 [[ZX]], [[XOR]] +; CHECK-NEXT: [[SH_MASK:%.*]] = and i16 [[SUB]], 511 +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[SH_MASK]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %zx = zext i8 %x to i16 ; zx = 0x00xx + %xor = xor i16 %zx, 32767 ; xor = 0x7fyy + %sub = sub nsw i16 %zx, %xor ; sub = 0x80zz (the top bit is known one) + %sh = shl nsw i16 %sub, 2 ; oops! this shl can't be nsw; that's POISON + %cmp = icmp ne i16 %sh, 1 + ret i1 %cmp +} +