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 @@ -67,9 +67,13 @@ case Instruction::AShr: case Instruction::UDiv: case Instruction::URem: + case Instruction::InsertElement: 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)); @@ -138,6 +142,8 @@ case Instruction::AShr: case Instruction::UDiv: case Instruction::URem: + case Instruction::InsertElement: + case Instruction::ExtractElement: case Instruction::Select: { SmallVector Operands; getRelevantOperands(I, Operands); @@ -146,7 +152,7 @@ } default: // TODO: Can handle more cases here: - // 1. shufflevector, extractelement, insertelement + // 1. shufflevector // 2. sdiv, srem // 3. phi node(and loop handling) // ... @@ -425,6 +431,19 @@ 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::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 @@ -43,12 +43,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 +59,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 @@ -74,13 +72,12 @@ ; This demonstrates test not folded by 'opt -instcombine' define <2 x i16> @extract_mul_insert(<2 x i8> %x) { ; CHECK-LABEL: @extract_mul_insert( -; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32> -; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> [[ZEXT]], -; CHECK-NEXT: [[EXTR:%.*]] = extractelement <2 x i32> [[LSHR]], i32 1 -; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[EXTR]], 5 -; CHECK-NEXT: [[INSR:%.*]] = insertelement <2 x i32> [[LSHR]], i32 [[MUL]], i32 1 -; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i32> [[INSR]] to <2 x i16> -; CHECK-NEXT: ret <2 x i16> [[TRUNC]] +; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16> +; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i16> [[ZEXT]], +; CHECK-NEXT: [[EXTR:%.*]] = extractelement <2 x i16> [[LSHR]], i32 1 +; CHECK-NEXT: [[MUL:%.*]] = mul i16 [[EXTR]], 5 +; CHECK-NEXT: [[INSR:%.*]] = insertelement <2 x i16> [[LSHR]], i16 [[MUL]], i32 1 +; CHECK-NEXT: ret <2 x i16> [[INSR]] ; %zext = zext <2 x i8> %x to <2 x i32> %lshr = lshr <2 x i32> %zext,