From 4c36ecbe0e162155e6032aec75323dcdd7c81b90 Mon Sep 17 00:00:00 2001 From: Quentin Dian Date: Wed, 6 Mar 2024 06:16:28 +0800 Subject: [PATCH] [InstCombine] Fix shift calculation in InstCombineCasts (#84027) Fixes #84025. (cherry picked from commit e96c0c1d5e0a9916098b1a31acb006ea6c1108fb) --- .../Transforms/InstCombine/InstCombineCasts.cpp | 4 ++-- llvm/test/Transforms/InstCombine/bitcast.ll | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 58f0763bb0c0cd..c5d3f60176a826 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -2156,14 +2156,14 @@ static bool collectInsertionElements(Value *V, unsigned Shift, Type *ElementIntTy = IntegerType::get(C->getContext(), ElementSize); for (unsigned i = 0; i != NumElts; ++i) { - unsigned ShiftI = Shift + i * ElementSize; + unsigned ShiftI = i * ElementSize; Constant *Piece = ConstantFoldBinaryInstruction( Instruction::LShr, C, ConstantInt::get(C->getType(), ShiftI)); if (!Piece) return false; Piece = ConstantExpr::getTrunc(Piece, ElementIntTy); - if (!collectInsertionElements(Piece, ShiftI, Elements, VecEltTy, + if (!collectInsertionElements(Piece, ShiftI + Shift, Elements, VecEltTy, isBigEndian)) return false; } diff --git a/llvm/test/Transforms/InstCombine/bitcast.ll b/llvm/test/Transforms/InstCombine/bitcast.ll index 58bd81297b0dd9..5ace1039c37825 100644 --- a/llvm/test/Transforms/InstCombine/bitcast.ll +++ b/llvm/test/Transforms/InstCombine/bitcast.ll @@ -686,6 +686,21 @@ define ptr @bitcast_from_single_element_pointer_vector_to_pointer(<1 x ptr> %ptr ret ptr %ptr } +; Sure that we calculate the correct shift. +define <4 x i32> @bitcast_shl(i32 %arg) { +; CHECK-LABEL: @bitcast_shl( +; CHECK-NEXT: [[I5:%.*]] = insertelement <4 x i32> , i32 [[ARG:%.*]], i64 3 +; CHECK-NEXT: ret <4 x i32> [[I5]] +; + %i = zext i32 %arg to i64 + %i1 = shl i64 %i, 32 + %i2 = or i64 %i1, 65 + %i3 = zext i64 %i2 to i128 + %i4 = shl i128 %i3, 64 + %i5 = bitcast i128 %i4 to <4 x i32> + ret <4 x i32> %i5 +} + declare void @f1() declare void @f2() define ptr @select_bitcast_unsized_pointer(i1 %c) {