; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=instcombine -S | FileCheck %s

define void @test_poison(float %b, ptr %p) {
; CHECK-LABEL: define void @test_poison(
; CHECK-SAME: float [[B:%.*]], ptr [[P:%.*]]) {
; CHECK-NEXT:    [[TMP1:%.*]] = load <8 x float>, ptr [[P]], align 32
; CHECK-NEXT:    [[TMP2:%.*]] = fptosi float [[B]] to i32
; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[TMP2]], -2
; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <8 x float> [[TMP1]], i32 [[TMP3]]
; CHECK-NEXT:    [[TMP5:%.*]] = fptosi float [[TMP4]] to i32
; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <8 x i32> poison, i32 [[TMP5]], i64 7
; CHECK-NEXT:    [[TMP7:%.*]] = sitofp <8 x i32> [[TMP6]] to <8 x float>
; CHECK-NEXT:    store <8 x float> [[TMP7]], ptr [[P]], align 32
; CHECK-NEXT:    ret void
;
  %1 = load <8 x float>, ptr %p
  %2 = bitcast <8 x float> %1 to <8 x i32>
  %3 = bitcast <8 x i32> %2 to <8 x float>
  %a = fptosi <8 x float> %3 to <8 x i32>
  %4 = fptosi float %b to i32
  %5 = add i32 %4, -2
  %6 = extractelement <8 x i32> %a, i32 %5
  %7 = insertelement <8 x i32> poison, i32 %6, i32 7
  %8 = sitofp <8 x i32> %7 to <8 x float>
  store <8 x float> %8, ptr %p
  ret void
}

; PR18600
define i32 @test_bitcast(i32 %i) {
; CHECK-LABEL: define i32 @test_bitcast(
; CHECK-SAME: i32 [[I:%.*]]) {
; CHECK-NEXT:    [[E:%.*]] = extractelement <4 x i32> <i32 1, i32 0, i32 2, i32 0>, i32 [[I]]
; CHECK-NEXT:    ret i32 [[E]]
;
  %e = extractelement <4 x i32> bitcast (<2 x i64> <i64 1, i64 2> to <4 x i32>), i32 %i
  ret i32 %e
}

declare void @use(i32)

define void @test_loop(<4 x float> %in) {
; CHECK-LABEL: define void @test_loop(
; CHECK-SAME: <4 x float> [[IN:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*]]:
; CHECK-NEXT:    [[R:%.*]] = call <4 x float> @llvm.x86.sse41.round.ps(<4 x float> [[IN]], i32 9)
; CHECK-NEXT:    br label %[[LOOP:.*]]
; CHECK:       [[LOOP]]:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[NEXT:%.*]], %[[LATCH:.*]] ]
; CHECK-NEXT:    [[COND:%.*]] = icmp samesign ult i32 [[I]], 4
; CHECK-NEXT:    br i1 [[COND]], label %[[BODY:.*]], label %[[DONE:.*]]
; CHECK:       [[BODY]]:
; CHECK-NEXT:    [[TMP0:%.*]] = extractelement <4 x float> [[R]], i32 [[I]]
; CHECK-NEXT:    [[ELEM:%.*]] = fptosi float [[TMP0]] to i32
; CHECK-NEXT:    call void @use(i32 [[ELEM]])
; CHECK-NEXT:    br label %[[LATCH]]
; CHECK:       [[LATCH]]:
; CHECK-NEXT:    [[NEXT]] = add nuw nsw i32 [[I]], 1
; CHECK-NEXT:    br label %[[LOOP]]
; CHECK:       [[DONE]]:
; CHECK-NEXT:    ret void
;
entry:
  %r = call <4 x float> @llvm.x86.sse41.round.ps(<4 x float> %in, i32 9)
  %vi = fptosi <4 x float> %r to <4 x i32>
  br label %loop
loop:
  %i = phi i32 [ 0, %entry ], [ %next, %latch ]
  %cond = icmp ult i32 %i, 4
  br i1 %cond, label %body, label %done
body:
  %elem = extractelement <4 x i32> %vi, i32 %i
  call void @use(i32 %elem)
  br label %latch
latch:
  %next = add i32 %i, 1
  br label %loop
done:
  ret void
}
