diff --git a/llvm/lib/CodeGen/TypePromotion.cpp b/llvm/lib/CodeGen/TypePromotion.cpp --- a/llvm/lib/CodeGen/TypePromotion.cpp +++ b/llvm/lib/CodeGen/TypePromotion.cpp @@ -484,7 +484,10 @@ continue; if (auto *Const = dyn_cast<ConstantInt>(Op)) { - Constant *NewConst = (SafeWrap.contains(I) && i == 1) + // For ICmp, the constant can be on the LHS or RHS. For Add/Sub the + // constant we checked for sext is on the RHS. + Constant *NewConst = (SafeWrap.contains(I) && + (I->getOpcode() == Instruction::ICmp || i == 1)) ? ConstantExpr::getSExt(Const, ExtTy) : ConstantExpr::getZExt(Const, ExtTy); I->setOperand(i, NewConst); diff --git a/llvm/test/Transforms/TypePromotion/ARM/icmps.ll b/llvm/test/Transforms/TypePromotion/ARM/icmps.ll --- a/llvm/test/Transforms/TypePromotion/ARM/icmps.ll +++ b/llvm/test/Transforms/TypePromotion/ARM/icmps.ll @@ -319,6 +319,24 @@ ret i32 %conv1 } +define i32 @icmp_minus_imm_noncanonicalcmp(i8* %a) { +; CHECK-LABEL: @icmp_minus_imm_noncanonicalcmp( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i32 +; CHECK-NEXT: [[ADD_I:%.*]] = add i32 [[TMP1]], -7 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 -5, [[ADD_I]] +; CHECK-NEXT: [[CONV1:%.*]] = zext i1 [[CMP]] to i32 +; CHECK-NEXT: ret i32 [[CONV1]] +; +entry: + %0 = load i8, i8* %a, align 1 + %add.i = add i8 %0, -7 + %cmp = icmp ult i8 -5, %add.i + %conv1 = zext i1 %cmp to i32 + ret i32 %conv1 +} + define void @mul_with_neg_imm(i32, i32* %b) { ; CHECK-LABEL: @mul_with_neg_imm( ; CHECK-NEXT: entry: