diff --git a/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp --- a/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp +++ b/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp @@ -66,9 +66,14 @@ case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: + case Instruction::InsertElement: + case Instruction::ShuffleVector: Ops.push_back(I->getOperand(0)); Ops.push_back(I->getOperand(1)); break; + case Instruction::ExtractElement: + Ops.push_back(I->getOperand(0)); + break; case Instruction::Select: Ops.push_back(I->getOperand(1)); Ops.push_back(I->getOperand(2)); @@ -135,6 +140,9 @@ case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: + case Instruction::InsertElement: + case Instruction::ExtractElement: + case Instruction::ShuffleVector: case Instruction::Select: { SmallVector Operands; getRelevantOperands(I, Operands); @@ -143,9 +151,8 @@ } default: // TODO: Can handle more cases here: - // 1. shufflevector, extractelement, insertelement - // 2. udiv, urem - // 3. phi node(and loop handling) + // 1. udiv, urem + // 2. phi node(and loop handling) // ... return false; } @@ -408,6 +415,26 @@ ResI->setIsExact(PEO->isExact()); break; } + case Instruction::ExtractElement: { + Value *Vec = getReducedOperand(I->getOperand(0), SclTy); + Value *Idx = I->getOperand(1); + Res = Builder.CreateExtractElement(Vec, Idx); + break; + } + case Instruction::InsertElement: { + Value *Vec = getReducedOperand(I->getOperand(0), SclTy); + Value *NewElt = getReducedOperand(I->getOperand(1), SclTy); + Value *Idx = I->getOperand(2); + Res = Builder.CreateInsertElement(Vec, NewElt, Idx); + break; + } + case Instruction::ShuffleVector: { + Value *V1 = getReducedOperand(I->getOperand(0), SclTy); + Value *V2 = getReducedOperand(I->getOperand(1), SclTy); + Res = Builder.CreateShuffleVector( + V1, V2, cast(I)->getShuffleMask()); + break; + } case Instruction::Select: { Value *Op0 = I->getOperand(0); Value *LHS = getReducedOperand(I->getOperand(1), SclTy); diff --git a/llvm/test/Transforms/AggressiveInstCombine/trunc_vector_instrs.ll b/llvm/test/Transforms/AggressiveInstCombine/trunc_vector_instrs.ll --- a/llvm/test/Transforms/AggressiveInstCombine/trunc_vector_instrs.ll +++ b/llvm/test/Transforms/AggressiveInstCombine/trunc_vector_instrs.ll @@ -3,11 +3,10 @@ define <4 x i16> @shuffle(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @shuffle( -; CHECK-NEXT: [[ZEXTA:%.*]] = zext <2 x i8> [[A:%.*]] to <2 x i32> -; CHECK-NEXT: [[ZEXTB:%.*]] = zext <2 x i8> [[B:%.*]] to <2 x i32> -; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i32> [[ZEXTA]], <2 x i32> [[ZEXTB]], <4 x i32> -; CHECK-NEXT: [[TRUNC:%.*]] = trunc <4 x i32> [[SHUF]] to <4 x i16> -; CHECK-NEXT: ret <4 x i16> [[TRUNC]] +; CHECK-NEXT: [[ZEXTA:%.*]] = zext <2 x i8> [[A:%.*]] to <2 x i16> +; CHECK-NEXT: [[ZEXTB:%.*]] = zext <2 x i8> [[B:%.*]] to <2 x i16> +; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i16> [[ZEXTA]], <2 x i16> [[ZEXTB]], <4 x i32> +; CHECK-NEXT: ret <4 x i16> [[SHUF]] ; %zexta = zext <2 x i8> %a to <2 x i32> %zextb = zext <2 x i8> %b to <2 x i32> @@ -18,10 +17,9 @@ define <2 x i16> @unary_shuffle(<2 x i8> %a) { ; CHECK-LABEL: @unary_shuffle( -; CHECK-NEXT: [[ZEXTA:%.*]] = zext <2 x i8> [[A:%.*]] to <2 x i32> -; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i32> [[ZEXTA]], <2 x i32> undef, <2 x i32> -; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i32> [[SHUF]] to <2 x i16> -; CHECK-NEXT: ret <2 x i16> [[TRUNC]] +; CHECK-NEXT: [[ZEXTA:%.*]] = zext <2 x i8> [[A:%.*]] to <2 x i16> +; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i16> [[ZEXTA]], <2 x i16> undef, <2 x i32> +; CHECK-NEXT: ret <2 x i16> [[SHUF]] ; %zexta = zext <2 x i8> %a to <2 x i32> %shuf = shufflevector <2 x i32> %zexta, <2 x i32> undef, <2 x i32> @@ -31,9 +29,7 @@ define <4 x i16> @const_shuffle() { ; CHECK-LABEL: @const_shuffle( -; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i32> , <2 x i32> , <4 x i32> -; CHECK-NEXT: [[TRUNC:%.*]] = trunc <4 x i32> [[SHUF]] to <4 x i16> -; CHECK-NEXT: ret <4 x i16> [[TRUNC]] +; CHECK-NEXT: ret <4 x i16> ; %shuf = shufflevector <2 x i32> , <2 x i32> , <4 x i32> %trunc = trunc <4 x i32> %shuf to <4 x i16> @@ -43,12 +39,11 @@ define <2 x i16> @extract_insert(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @extract_insert( -; CHECK-NEXT: [[ZEXTA:%.*]] = zext <2 x i8> [[A:%.*]] to <2 x i32> -; CHECK-NEXT: [[ZEXTB:%.*]] = zext <2 x i8> [[B:%.*]] to <2 x i32> -; CHECK-NEXT: [[EXTR:%.*]] = extractelement <2 x i32> [[ZEXTA]], i32 0 -; CHECK-NEXT: [[INSR:%.*]] = insertelement <2 x i32> [[ZEXTB]], i32 [[EXTR]], i32 1 -; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i32> [[INSR]] to <2 x i16> -; CHECK-NEXT: ret <2 x i16> [[TRUNC]] +; CHECK-NEXT: [[ZEXTA:%.*]] = zext <2 x i8> [[A:%.*]] to <2 x i16> +; CHECK-NEXT: [[ZEXTB:%.*]] = zext <2 x i8> [[B:%.*]] to <2 x i16> +; CHECK-NEXT: [[EXTR:%.*]] = extractelement <2 x i16> [[ZEXTA]], i32 0 +; CHECK-NEXT: [[INSR:%.*]] = insertelement <2 x i16> [[ZEXTB]], i16 [[EXTR]], i32 1 +; CHECK-NEXT: ret <2 x i16> [[INSR]] ; %zexta = zext <2 x i8> %a to <2 x i32> %zextb = zext <2 x i8> %b to <2 x i32> @@ -60,10 +55,9 @@ define <2 x i16> @insert_poison(i8 %a) { ; CHECK-LABEL: @insert_poison( -; CHECK-NEXT: [[ZEXTA:%.*]] = zext i8 [[A:%.*]] to i32 -; CHECK-NEXT: [[INSR:%.*]] = insertelement <2 x i32> poison, i32 [[ZEXTA]], i32 0 -; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i32> [[INSR]] to <2 x i16> -; CHECK-NEXT: ret <2 x i16> [[TRUNC]] +; CHECK-NEXT: [[ZEXTA:%.*]] = zext i8 [[A:%.*]] to i16 +; CHECK-NEXT: [[INSR:%.*]] = insertelement <2 x i16> poison, i16 [[ZEXTA]], i32 0 +; CHECK-NEXT: ret <2 x i16> [[INSR]] ; %zexta = zext i8 %a to i32 %insr = insertelement <2 x i32> poison, i32 %zexta, i32 0