Index: llvm/lib/CodeGen/TypePromotion.cpp =================================================================== --- llvm/lib/CodeGen/TypePromotion.cpp +++ llvm/lib/CodeGen/TypePromotion.cpp @@ -260,7 +260,7 @@ if (auto *ICmp = dyn_cast(V)) return ICmp->isSigned() || LessThanTypeSize(ICmp->getOperand(0)); - return isa(V); + return isa(V) || isa(V); } /// Return whether this instruction can safely wrap. @@ -704,6 +704,7 @@ case Instruction::BitCast: return isSupportedType(I); case Instruction::ZExt: + case Instruction::SExt: return isSupportedType(I->getOperand(0)); case Instruction::ICmp: // Now that we allow small types than TypeSize, only allow icmp of Index: llvm/test/Transforms/TypePromotion/ARM/casts.ll =================================================================== --- llvm/test/Transforms/TypePromotion/ARM/casts.ll +++ llvm/test/Transforms/TypePromotion/ARM/casts.ll @@ -166,24 +166,27 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i16, i16* [[PTR:%.*]], i32 0 ; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[GEP]], align 1 -; CHECK-NEXT: [[TMP1:%.*]] = sub nuw nsw i16 [[TMP0]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[TMP0]] to i32 +; CHECK-NEXT: [[TMP2:%.*]] = sub nuw nsw i32 [[TMP1]], 1 ; CHECK-NEXT: [[CONV44:%.*]] = zext i16 [[TMP0]] to i32 ; CHECK-NEXT: br label [[PREHEADER:%.*]] ; CHECK: preheader: ; CHECK-NEXT: br label [[BODY:%.*]] ; CHECK: body: -; CHECK-NEXT: [[TMP2:%.*]] = phi i16 [ [[TMP1]], [[PREHEADER]] ], [ [[TMP3:%.*]], [[IF_END:%.*]] ] +; CHECK-NEXT: [[TMP3:%.*]] = phi i32 [ [[TMP2]], [[PREHEADER]] ], [ [[TMP6:%.*]], [[IF_END:%.*]] ] ; CHECK-NEXT: [[SI_0274:%.*]] = phi i32 [ [[CONV44]], [[PREHEADER]] ], [ [[INC:%.*]], [[IF_END]] ] -; CHECK-NEXT: [[CONV51266:%.*]] = zext i16 [[TMP2]] to i32 -; CHECK-NEXT: [[CMP52267:%.*]] = icmp eq i32 [[SI_0274]], [[CONV51266]] +; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16 +; CHECK-NEXT: [[CMP52267:%.*]] = icmp eq i32 [[SI_0274]], [[TMP3]] ; CHECK-NEXT: br i1 [[CMP52267]], label [[IF_END]], label [[EXIT:%.*]] ; CHECK: if.end: ; CHECK-NEXT: [[INC]] = add i32 [[SI_0274]], 1 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i16, i16* [[PTR]], i32 [[INC]] -; CHECK-NEXT: [[TMP3]] = load i16, i16* [[GEP1]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = load i16, i16* [[GEP1]], align 1 +; CHECK-NEXT: [[TMP6]] = zext i16 [[TMP5]] to i32 ; CHECK-NEXT: br label [[BODY]] ; CHECK: exit: -; CHECK-NEXT: [[RET:%.*]] = sext i16 [[TMP2]] to i32 +; CHECK-NEXT: [[TMP7:%.*]] = trunc i32 [[TMP3]] to i16 +; CHECK-NEXT: [[RET:%.*]] = sext i16 [[TMP7]] to i32 ; CHECK-NEXT: ret i32 [[RET]] ; entry: @@ -990,19 +993,23 @@ ; CHECK-LABEL: @and_trunc_two_zext( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @c, align 2 -; CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @b, align 2 -; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[TMP1]] to i32 +; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[TMP0]] to i32 +; CHECK-NEXT: [[TMP2:%.*]] = load i16, i16* @b, align 2 +; CHECK-NEXT: [[TMP3:%.*]] = zext i16 [[TMP2]] to i32 +; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16 +; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[TMP4]] to i32 ; CHECK-NEXT: store i32 [[CONV]], i32* @f, align 4 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i16 [[TMP1]] to i8 -; CHECK-NEXT: [[CONV1:%.*]] = and i8 [[TMP2]], 1 -; CHECK-NEXT: store i8 [[CONV1]], i8* @e, align 1 -; CHECK-NEXT: [[TMP3:%.*]] = load i8, i8* @a, align 1 -; CHECK-NEXT: [[NARROW:%.*]] = mul nuw i8 [[TMP3]], [[CONV1]] -; CHECK-NEXT: [[MUL:%.*]] = zext i8 [[NARROW]] to i32 -; CHECK-NEXT: store i32 [[MUL]], i32* @d, align 4 -; CHECK-NEXT: [[TMP4:%.*]] = zext i8 [[NARROW]] to i16 -; CHECK-NEXT: [[CONV5:%.*]] = or i16 [[TMP0]], [[TMP4]] -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i16 [[CONV5]], 0 +; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP3]], 255 +; CHECK-NEXT: [[CONV1:%.*]] = and i32 [[TMP5]], 1 +; CHECK-NEXT: [[TMP6:%.*]] = trunc i32 [[CONV1]] to i8 +; CHECK-NEXT: store i8 [[TMP6]], i8* @e, align 1 +; CHECK-NEXT: [[TMP7:%.*]] = load i8, i8* @a, align 1 +; CHECK-NEXT: [[TMP8:%.*]] = zext i8 [[TMP7]] to i32 +; CHECK-NEXT: [[NARROW:%.*]] = mul nuw i32 [[TMP8]], [[CONV1]] +; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[NARROW]] to i8 +; CHECK-NEXT: store i32 [[NARROW]], i32* @d, align 4 +; CHECK-NEXT: [[CONV5:%.*]] = or i32 [[TMP1]], [[NARROW]] +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[CONV5]], 0 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[FOR_COND:%.*]] ; CHECK: for.cond: ; CHECK-NEXT: br label [[FOR_COND]] @@ -1074,19 +1081,23 @@ ; CHECK-LABEL: @dont_replace_trunc_1( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[C:%.*]], align 2 -; CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* [[B:%.*]], align 2 -; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[TMP1]] to i32 +; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[TMP0]] to i32 +; CHECK-NEXT: [[TMP2:%.*]] = load i16, i16* [[B:%.*]], align 2 +; CHECK-NEXT: [[TMP3:%.*]] = zext i16 [[TMP2]] to i32 +; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16 +; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[TMP4]] to i32 ; CHECK-NEXT: store i32 [[CONV]], i32* [[F:%.*]], align 4 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i16 [[TMP1]] to i8 -; CHECK-NEXT: [[CONV1:%.*]] = and i8 [[TMP2]], 1 -; CHECK-NEXT: store i8 [[CONV1]], i8* [[E:%.*]], align 1 -; CHECK-NEXT: [[TMP3:%.*]] = load i8, i8* [[A:%.*]], align 1 -; CHECK-NEXT: [[NARROW:%.*]] = mul nuw i8 [[TMP3]], [[CONV1]] -; CHECK-NEXT: [[MUL:%.*]] = zext i8 [[NARROW]] to i32 -; CHECK-NEXT: store i32 [[MUL]], i32* [[D:%.*]], align 4 -; CHECK-NEXT: [[TMP4:%.*]] = zext i8 [[NARROW]] to i16 -; CHECK-NEXT: [[CONV5:%.*]] = or i16 [[TMP0]], [[TMP4]] -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i16 [[CONV5]], 0 +; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP3]], 255 +; CHECK-NEXT: [[CONV1:%.*]] = and i32 [[TMP5]], 1 +; CHECK-NEXT: [[TMP6:%.*]] = trunc i32 [[CONV1]] to i8 +; CHECK-NEXT: store i8 [[TMP6]], i8* [[E:%.*]], align 1 +; CHECK-NEXT: [[TMP7:%.*]] = load i8, i8* [[A:%.*]], align 1 +; CHECK-NEXT: [[TMP8:%.*]] = zext i8 [[TMP7]] to i32 +; CHECK-NEXT: [[NARROW:%.*]] = mul nuw i32 [[TMP8]], [[CONV1]] +; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[NARROW]] to i8 +; CHECK-NEXT: store i32 [[NARROW]], i32* [[D:%.*]], align 4 +; CHECK-NEXT: [[CONV5:%.*]] = or i32 [[TMP1]], [[NARROW]] +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[CONV5]], 0 ; CHECK-NEXT: ret i1 [[TOBOOL]] ; entry: