Bug type: miscompilation
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp: collectInsertionElements
Issue title: InstCombine calculated a wrong `insertelement` instruction
Labels: miscompilation
llvm:instcombine
Reported by: DianQK

I tried this IR:

```llvm
define <4 x i32> @src(i32 %arg) {
  %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
}

define <4 x i32> @tgt(i32 %arg) {
  %i5 = insertelement <4 x i32> <i32 0, i32 0, i32 0, i32 poison>, i32 %arg, i64 3
  ret <4 x i32> %i5
}
```

I expect `src` to be:

```llvm
define <4 x i32> @src(i32 %arg) {
  %i5 = insertelement <4 x i32> <i32 0, i32 0, i32 65, i32 poison>, i32 %arg, i64 3
  ret <4 x i32> %i5
}
```

But I'm getting the same instructions as `tgt`.

Godbolt: https://llvm.godbolt.org/z/KnMEY4rTq
Alive2: https://alive2.llvm.org/ce/z/7FIJNi
From: https://github.com/rust-lang/rust/issues/121996

Comments: author: cbeuw
body: Looks like this bug is almost 11 years old: https://github.com/llvm/llvm-project/commit/feb34713d531d1f48c37116e8cab84814202d057! Thanks for fixing
author: DianQK
body: > Looks like this bug is almost 11 years old: [feb3471](https://github.com/llvm/llvm-project/commit/feb34713d531d1f48c37116e8cab84814202d057)! Thanks for fixing

Based on my experience, we likely have many more latent bugs. :)

Fix patch:
commit e96c0c1d5e0a9916098b1a31acb006ea6c1108fb
Author: Quentin Dian <dianqk@dianqk.net>
Date:   Wed Mar 6 06:16:28 2024 +0800

     [InstCombine] Fix shift calculation in InstCombineCasts (#84027)
    
    Fixes #84025.

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 33ed1d557537..45afa6363ae0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -2167,14 +2167,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;
     }


Regression tests:
file: llvm/test/Transforms/InstCombine/bitcast.ll
commands: opt < %s -passes=instcombine -S
tests: test_name: bitcast_from_single_element_pointer_vector_to_pointer
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin10.0.0"

define ptr @bitcast_from_single_element_pointer_vector_to_pointer(<1 x ptr> %ptrvec) {
  %ptr = bitcast <1 x ptr> %ptrvec to ptr
  ret ptr %ptr
}

test_name: bitcast_shl
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin10.0.0"

define <4 x i32> @bitcast_shl(i32 %arg) {
  %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
}

test_name: select_bitcast_unsized_pointer
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin10.0.0"

declare void @f1()

declare void @f2()

define ptr @select_bitcast_unsized_pointer(i1 %c) {
  %s = select i1 %c, ptr @f1, ptr @f2
  ret ptr %s
}