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 @@ -579,7 +579,6 @@ LLVM_DEBUG(dbgs() << "IR Promotion: Cleanup..\n"); // Some zexts will now have become redundant, along with their trunc // operands, so remove them. - // Some zexts need to be replaced with truncate if src bitwidth is larger. for (auto *V : Visited) { if (!isa(V)) continue; @@ -594,11 +593,6 @@ << "\n"); ReplaceAllUsersOfWith(ZExt, Src); continue; - } else if (ZExt->getSrcTy()->getScalarSizeInBits() > PromotedWidth) { - IRBuilder<> Builder{ZExt}; - Value *Trunc = Builder.CreateTrunc(Src, ZExt->getDestTy()); - ReplaceAllUsersOfWith(ZExt, Trunc); - continue; } // We've inserted a trunc for a zext sink, but we already know that the @@ -634,6 +628,8 @@ ConstantInt *Mask = ConstantInt::get(SrcTy, APInt::getMaxValue(NumBits).getZExtValue()); Value *Masked = Builder.CreateAnd(Trunc->getOperand(0), Mask); + if (SrcTy != ExtTy) + Masked = Builder.CreateTrunc(Masked, ExtTy); if (auto *I = dyn_cast(Masked)) NewInsts.insert(I); diff --git a/llvm/test/Transforms/TypePromotion/AArch64/pr58843.ll b/llvm/test/Transforms/TypePromotion/AArch64/pr58843.ll deleted file mode 100644 --- a/llvm/test/Transforms/TypePromotion/AArch64/pr58843.ll +++ /dev/null @@ -1,20 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -mtriple=aarch64 -type-promotion -verify -S %s -o - | FileCheck %s -target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" - -; Check the case don't crash due to zext source type bitwidth -; larger than dest type bitwidth. -define i1 @test(i8 %arg) { -; CHECK-LABEL: @test( -; CHECK-NEXT: [[EXT1:%.*]] = zext i8 [[ARG:%.*]] to i64 -; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[EXT1]], 7 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0 -; CHECK-NEXT: ret i1 [[CMP]] -; - %ext1 = zext i8 %arg to i64 - %trunc = trunc i64 %ext1 to i3 - %ext2 = zext i3 %trunc to i8 - %cmp = icmp ne i8 %ext2, 0 - ret i1 %cmp -} diff --git a/llvm/test/Transforms/TypePromotion/AArch64/trunc-zext-chain.ll b/llvm/test/Transforms/TypePromotion/AArch64/trunc-zext-chain.ll --- a/llvm/test/Transforms/TypePromotion/AArch64/trunc-zext-chain.ll +++ b/llvm/test/Transforms/TypePromotion/AArch64/trunc-zext-chain.ll @@ -177,3 +177,39 @@ exit: ret i64 %var30 } + +; Check the case don't crash due to zext source type bitwidth +; larger than dest type bitwidth. +define i1 @pr58843(i8 %arg) { +; CHECK-LABEL: @pr58843( +; CHECK-NEXT: [[EXT1:%.*]] = zext i8 [[ARG:%.*]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[EXT1]], 7 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %ext1 = zext i8 %arg to i64 + %trunc = trunc i64 %ext1 to i3 + %ext2 = zext i3 %trunc to i8 + %cmp = icmp ne i8 %ext2, 0 + ret i1 %cmp +} + +; Check the case don't crash due to xor two op have different +; types +define i1 @pr59554(i8 %arg) { +; CHECK-LABEL: @pr59554( +; CHECK-NEXT: [[ARG_EXT:%.*]] = zext i8 [[ARG:%.*]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[ARG_EXT]], 7 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = xor i32 [[TMP2]], 1 +; CHECK-NEXT: [[SWITCH_LOBIT:%.*]] = icmp ne i32 [[TMP2]], 0 +; CHECK-NEXT: ret i1 [[SWITCH_LOBIT]] +; + %arg.ext = zext i8 %arg to i64 + %trunc = trunc i64 %arg.ext to i3 + %switch.tableidx = xor i3 %trunc, 1 + %switch.maskindex = zext i3 %trunc to i8 + %switch.lobit = icmp ne i8 %switch.maskindex, 0 + ret i1 %switch.lobit +}