Files
clang-p2996/llvm/test/Transforms/SLPVectorizer/X86/intrinsic.ll
Roman Lebedev 3f1f08f0ed Revert @llvm.isnan intrinsic patchset.
Please refer to
https://lists.llvm.org/pipermail/llvm-dev/2021-September/152440.html
(and that whole thread.)

TLDR: the original patch had no prior RFC, yet it had some changes that
really need a proper RFC discussion. It won't be productive to discuss
such an RFC, once it's actually posted, while said patch is already
committed, because that introduces bias towards already-committed stuff,
and the tree is potentially in broken state meanwhile.

While the end result of discussion may lead back to the current design,
it may also not lead to the current design.

Therefore i take it upon myself
to revert the tree back to last known good state.

This reverts commit 4c4093e6e3.
This reverts commit 0a2b1ba33a.
This reverts commit d9873711cb.
This reverts commit 791006fb8c.
This reverts commit c22b64ef66.
This reverts commit 72ebcd3198.
This reverts commit 5fa6039a5f.
This reverts commit 9efda541bf.
This reverts commit 94d3ff09cf.
2021-09-02 13:53:56 +03:00

516 lines
24 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -basic-aa -slp-vectorizer -slp-threshold=-999 -dce -S -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck %s
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-S128"
target triple = "x86_64-apple-macosx10.8.0"
declare double @llvm.fabs.f64(double) nounwind readnone
define void @vec_fabs_f64(double* %a, double* %b, double* %c) {
; CHECK-LABEL: @vec_fabs_f64(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = bitcast double* [[A:%.*]] to <2 x double>*
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x double>, <2 x double>* [[TMP0]], align 8
; CHECK-NEXT: [[TMP2:%.*]] = bitcast double* [[B:%.*]] to <2 x double>*
; CHECK-NEXT: [[TMP3:%.*]] = load <2 x double>, <2 x double>* [[TMP2]], align 8
; CHECK-NEXT: [[TMP4:%.*]] = fmul <2 x double> [[TMP1]], [[TMP3]]
; CHECK-NEXT: [[TMP5:%.*]] = call <2 x double> @llvm.fabs.v2f64(<2 x double> [[TMP4]])
; CHECK-NEXT: [[TMP6:%.*]] = bitcast double* [[C:%.*]] to <2 x double>*
; CHECK-NEXT: store <2 x double> [[TMP5]], <2 x double>* [[TMP6]], align 8
; CHECK-NEXT: ret void
;
entry:
%i0 = load double, double* %a, align 8
%i1 = load double, double* %b, align 8
%mul = fmul double %i0, %i1
%call = tail call double @llvm.fabs.f64(double %mul) nounwind readnone
%arrayidx3 = getelementptr inbounds double, double* %a, i64 1
%i3 = load double, double* %arrayidx3, align 8
%arrayidx4 = getelementptr inbounds double, double* %b, i64 1
%i4 = load double, double* %arrayidx4, align 8
%mul5 = fmul double %i3, %i4
%call5 = tail call double @llvm.fabs.f64(double %mul5) nounwind readnone
store double %call, double* %c, align 8
%arrayidx5 = getelementptr inbounds double, double* %c, i64 1
store double %call5, double* %arrayidx5, align 8
ret void
}
declare float @llvm.copysign.f32(float, float) nounwind readnone
define void @vec_copysign_f32(float* %a, float* %b, float* noalias %c) {
; CHECK-LABEL: @vec_copysign_f32(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = bitcast float* [[A:%.*]] to <4 x float>*
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, <4 x float>* [[TMP0]], align 4
; CHECK-NEXT: [[TMP2:%.*]] = bitcast float* [[B:%.*]] to <4 x float>*
; CHECK-NEXT: [[TMP3:%.*]] = load <4 x float>, <4 x float>* [[TMP2]], align 4
; CHECK-NEXT: [[TMP4:%.*]] = call <4 x float> @llvm.copysign.v4f32(<4 x float> [[TMP1]], <4 x float> [[TMP3]])
; CHECK-NEXT: [[TMP5:%.*]] = bitcast float* [[C:%.*]] to <4 x float>*
; CHECK-NEXT: store <4 x float> [[TMP4]], <4 x float>* [[TMP5]], align 4
; CHECK-NEXT: ret void
;
entry:
%0 = load float, float* %a, align 4
%1 = load float, float* %b, align 4
%call0 = tail call float @llvm.copysign.f32(float %0, float %1) nounwind readnone
store float %call0, float* %c, align 4
%ix2 = getelementptr inbounds float, float* %a, i64 1
%2 = load float, float* %ix2, align 4
%ix3 = getelementptr inbounds float, float* %b, i64 1
%3 = load float, float* %ix3, align 4
%call1 = tail call float @llvm.copysign.f32(float %2, float %3) nounwind readnone
%c1 = getelementptr inbounds float, float* %c, i64 1
store float %call1, float* %c1, align 4
%ix4 = getelementptr inbounds float, float* %a, i64 2
%4 = load float, float* %ix4, align 4
%ix5 = getelementptr inbounds float, float* %b, i64 2
%5 = load float, float* %ix5, align 4
%call2 = tail call float @llvm.copysign.f32(float %4, float %5) nounwind readnone
%c2 = getelementptr inbounds float, float* %c, i64 2
store float %call2, float* %c2, align 4
%ix6 = getelementptr inbounds float, float* %a, i64 3
%6 = load float, float* %ix6, align 4
%ix7 = getelementptr inbounds float, float* %b, i64 3
%7 = load float, float* %ix7, align 4
%call3 = tail call float @llvm.copysign.f32(float %6, float %7) nounwind readnone
%c3 = getelementptr inbounds float, float* %c, i64 3
store float %call3, float* %c3, align 4
ret void
}
declare i32 @llvm.bswap.i32(i32) nounwind readnone
define void @vec_bswap_i32(i32* %a, i32* %b, i32* %c) {
; CHECK-LABEL: @vec_bswap_i32(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[A:%.*]] to <4 x i32>*
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i32* [[B:%.*]] to <4 x i32>*
; CHECK-NEXT: [[TMP3:%.*]] = load <4 x i32>, <4 x i32>* [[TMP2]], align 4
; CHECK-NEXT: [[TMP4:%.*]] = add <4 x i32> [[TMP1]], [[TMP3]]
; CHECK-NEXT: [[TMP5:%.*]] = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> [[TMP4]])
; CHECK-NEXT: [[TMP6:%.*]] = bitcast i32* [[C:%.*]] to <4 x i32>*
; CHECK-NEXT: store <4 x i32> [[TMP5]], <4 x i32>* [[TMP6]], align 4
; CHECK-NEXT: ret void
;
entry:
%i0 = load i32, i32* %a, align 4
%i1 = load i32, i32* %b, align 4
%add1 = add i32 %i0, %i1
%call1 = tail call i32 @llvm.bswap.i32(i32 %add1) nounwind readnone
%arrayidx2 = getelementptr inbounds i32, i32* %a, i32 1
%i2 = load i32, i32* %arrayidx2, align 4
%arrayidx3 = getelementptr inbounds i32, i32* %b, i32 1
%i3 = load i32, i32* %arrayidx3, align 4
%add2 = add i32 %i2, %i3
%call2 = tail call i32 @llvm.bswap.i32(i32 %add2) nounwind readnone
%arrayidx4 = getelementptr inbounds i32, i32* %a, i32 2
%i4 = load i32, i32* %arrayidx4, align 4
%arrayidx5 = getelementptr inbounds i32, i32* %b, i32 2
%i5 = load i32, i32* %arrayidx5, align 4
%add3 = add i32 %i4, %i5
%call3 = tail call i32 @llvm.bswap.i32(i32 %add3) nounwind readnone
%arrayidx6 = getelementptr inbounds i32, i32* %a, i32 3
%i6 = load i32, i32* %arrayidx6, align 4
%arrayidx7 = getelementptr inbounds i32, i32* %b, i32 3
%i7 = load i32, i32* %arrayidx7, align 4
%add4 = add i32 %i6, %i7
%call4 = tail call i32 @llvm.bswap.i32(i32 %add4) nounwind readnone
store i32 %call1, i32* %c, align 4
%arrayidx8 = getelementptr inbounds i32, i32* %c, i32 1
store i32 %call2, i32* %arrayidx8, align 4
%arrayidx9 = getelementptr inbounds i32, i32* %c, i32 2
store i32 %call3, i32* %arrayidx9, align 4
%arrayidx10 = getelementptr inbounds i32, i32* %c, i32 3
store i32 %call4, i32* %arrayidx10, align 4
ret void
}
declare i32 @llvm.ctlz.i32(i32,i1) nounwind readnone
define void @vec_ctlz_i32(i32* %a, i32* %b, i32* %c, i1) {
; CHECK-LABEL: @vec_ctlz_i32(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A:%.*]] to <4 x i32>*
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, <4 x i32>* [[TMP1]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = bitcast i32* [[B:%.*]] to <4 x i32>*
; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i32>, <4 x i32>* [[TMP3]], align 4
; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i32> [[TMP2]], [[TMP4]]
; CHECK-NEXT: [[TMP6:%.*]] = call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> [[TMP5]], i1 true)
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i32* [[C:%.*]] to <4 x i32>*
; CHECK-NEXT: store <4 x i32> [[TMP6]], <4 x i32>* [[TMP7]], align 4
; CHECK-NEXT: ret void
;
entry:
%i0 = load i32, i32* %a, align 4
%i1 = load i32, i32* %b, align 4
%add1 = add i32 %i0, %i1
%call1 = tail call i32 @llvm.ctlz.i32(i32 %add1,i1 true) nounwind readnone
%arrayidx2 = getelementptr inbounds i32, i32* %a, i32 1
%i2 = load i32, i32* %arrayidx2, align 4
%arrayidx3 = getelementptr inbounds i32, i32* %b, i32 1
%i3 = load i32, i32* %arrayidx3, align 4
%add2 = add i32 %i2, %i3
%call2 = tail call i32 @llvm.ctlz.i32(i32 %add2,i1 true) nounwind readnone
%arrayidx4 = getelementptr inbounds i32, i32* %a, i32 2
%i4 = load i32, i32* %arrayidx4, align 4
%arrayidx5 = getelementptr inbounds i32, i32* %b, i32 2
%i5 = load i32, i32* %arrayidx5, align 4
%add3 = add i32 %i4, %i5
%call3 = tail call i32 @llvm.ctlz.i32(i32 %add3,i1 true) nounwind readnone
%arrayidx6 = getelementptr inbounds i32, i32* %a, i32 3
%i6 = load i32, i32* %arrayidx6, align 4
%arrayidx7 = getelementptr inbounds i32, i32* %b, i32 3
%i7 = load i32, i32* %arrayidx7, align 4
%add4 = add i32 %i6, %i7
%call4 = tail call i32 @llvm.ctlz.i32(i32 %add4,i1 true) nounwind readnone
store i32 %call1, i32* %c, align 4
%arrayidx8 = getelementptr inbounds i32, i32* %c, i32 1
store i32 %call2, i32* %arrayidx8, align 4
%arrayidx9 = getelementptr inbounds i32, i32* %c, i32 2
store i32 %call3, i32* %arrayidx9, align 4
%arrayidx10 = getelementptr inbounds i32, i32* %c, i32 3
store i32 %call4, i32* %arrayidx10, align 4
ret void
}
define void @vec_ctlz_i32_neg(i32* %a, i32* %b, i32* %c, i1) {
; CHECK-LABEL: @vec_ctlz_i32_neg(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[I0:%.*]] = load i32, i32* [[A:%.*]], align 4
; CHECK-NEXT: [[I1:%.*]] = load i32, i32* [[B:%.*]], align 4
; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[I0]], [[I1]]
; CHECK-NEXT: [[CALL1:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[ADD1]], i1 true) #[[ATTR3:[0-9]+]]
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 1
; CHECK-NEXT: [[I2:%.*]] = load i32, i32* [[ARRAYIDX2]], align 4
; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 1
; CHECK-NEXT: [[I3:%.*]] = load i32, i32* [[ARRAYIDX3]], align 4
; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[I2]], [[I3]]
; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[ADD2]], i1 false) #[[ATTR3]]
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 2
; CHECK-NEXT: [[I4:%.*]] = load i32, i32* [[ARRAYIDX4]], align 4
; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 2
; CHECK-NEXT: [[I5:%.*]] = load i32, i32* [[ARRAYIDX5]], align 4
; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[I4]], [[I5]]
; CHECK-NEXT: [[CALL3:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[ADD3]], i1 true) #[[ATTR3]]
; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 3
; CHECK-NEXT: [[I6:%.*]] = load i32, i32* [[ARRAYIDX6]], align 4
; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 3
; CHECK-NEXT: [[I7:%.*]] = load i32, i32* [[ARRAYIDX7]], align 4
; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[I6]], [[I7]]
; CHECK-NEXT: [[CALL4:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[ADD4]], i1 false) #[[ATTR3]]
; CHECK-NEXT: store i32 [[CALL1]], i32* [[C:%.*]], align 4
; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i32, i32* [[C]], i32 1
; CHECK-NEXT: store i32 [[CALL2]], i32* [[ARRAYIDX8]], align 4
; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i32, i32* [[C]], i32 2
; CHECK-NEXT: store i32 [[CALL3]], i32* [[ARRAYIDX9]], align 4
; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds i32, i32* [[C]], i32 3
; CHECK-NEXT: store i32 [[CALL4]], i32* [[ARRAYIDX10]], align 4
; CHECK-NEXT: ret void
;
entry:
%i0 = load i32, i32* %a, align 4
%i1 = load i32, i32* %b, align 4
%add1 = add i32 %i0, %i1
%call1 = tail call i32 @llvm.ctlz.i32(i32 %add1,i1 true) nounwind readnone
%arrayidx2 = getelementptr inbounds i32, i32* %a, i32 1
%i2 = load i32, i32* %arrayidx2, align 4
%arrayidx3 = getelementptr inbounds i32, i32* %b, i32 1
%i3 = load i32, i32* %arrayidx3, align 4
%add2 = add i32 %i2, %i3
%call2 = tail call i32 @llvm.ctlz.i32(i32 %add2,i1 false) nounwind readnone
%arrayidx4 = getelementptr inbounds i32, i32* %a, i32 2
%i4 = load i32, i32* %arrayidx4, align 4
%arrayidx5 = getelementptr inbounds i32, i32* %b, i32 2
%i5 = load i32, i32* %arrayidx5, align 4
%add3 = add i32 %i4, %i5
%call3 = tail call i32 @llvm.ctlz.i32(i32 %add3,i1 true) nounwind readnone
%arrayidx6 = getelementptr inbounds i32, i32* %a, i32 3
%i6 = load i32, i32* %arrayidx6, align 4
%arrayidx7 = getelementptr inbounds i32, i32* %b, i32 3
%i7 = load i32, i32* %arrayidx7, align 4
%add4 = add i32 %i6, %i7
%call4 = tail call i32 @llvm.ctlz.i32(i32 %add4,i1 false) nounwind readnone
store i32 %call1, i32* %c, align 4
%arrayidx8 = getelementptr inbounds i32, i32* %c, i32 1
store i32 %call2, i32* %arrayidx8, align 4
%arrayidx9 = getelementptr inbounds i32, i32* %c, i32 2
store i32 %call3, i32* %arrayidx9, align 4
%arrayidx10 = getelementptr inbounds i32, i32* %c, i32 3
store i32 %call4, i32* %arrayidx10, align 4
ret void
}
declare i32 @llvm.cttz.i32(i32,i1) nounwind readnone
define void @vec_cttz_i32(i32* %a, i32* %b, i32* %c, i1) {
; CHECK-LABEL: @vec_cttz_i32(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A:%.*]] to <4 x i32>*
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, <4 x i32>* [[TMP1]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = bitcast i32* [[B:%.*]] to <4 x i32>*
; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i32>, <4 x i32>* [[TMP3]], align 4
; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i32> [[TMP2]], [[TMP4]]
; CHECK-NEXT: [[TMP6:%.*]] = call <4 x i32> @llvm.cttz.v4i32(<4 x i32> [[TMP5]], i1 true)
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i32* [[C:%.*]] to <4 x i32>*
; CHECK-NEXT: store <4 x i32> [[TMP6]], <4 x i32>* [[TMP7]], align 4
; CHECK-NEXT: ret void
;
entry:
%i0 = load i32, i32* %a, align 4
%i1 = load i32, i32* %b, align 4
%add1 = add i32 %i0, %i1
%call1 = tail call i32 @llvm.cttz.i32(i32 %add1,i1 true) nounwind readnone
%arrayidx2 = getelementptr inbounds i32, i32* %a, i32 1
%i2 = load i32, i32* %arrayidx2, align 4
%arrayidx3 = getelementptr inbounds i32, i32* %b, i32 1
%i3 = load i32, i32* %arrayidx3, align 4
%add2 = add i32 %i2, %i3
%call2 = tail call i32 @llvm.cttz.i32(i32 %add2,i1 true) nounwind readnone
%arrayidx4 = getelementptr inbounds i32, i32* %a, i32 2
%i4 = load i32, i32* %arrayidx4, align 4
%arrayidx5 = getelementptr inbounds i32, i32* %b, i32 2
%i5 = load i32, i32* %arrayidx5, align 4
%add3 = add i32 %i4, %i5
%call3 = tail call i32 @llvm.cttz.i32(i32 %add3,i1 true) nounwind readnone
%arrayidx6 = getelementptr inbounds i32, i32* %a, i32 3
%i6 = load i32, i32* %arrayidx6, align 4
%arrayidx7 = getelementptr inbounds i32, i32* %b, i32 3
%i7 = load i32, i32* %arrayidx7, align 4
%add4 = add i32 %i6, %i7
%call4 = tail call i32 @llvm.cttz.i32(i32 %add4,i1 true) nounwind readnone
store i32 %call1, i32* %c, align 4
%arrayidx8 = getelementptr inbounds i32, i32* %c, i32 1
store i32 %call2, i32* %arrayidx8, align 4
%arrayidx9 = getelementptr inbounds i32, i32* %c, i32 2
store i32 %call3, i32* %arrayidx9, align 4
%arrayidx10 = getelementptr inbounds i32, i32* %c, i32 3
store i32 %call4, i32* %arrayidx10, align 4
ret void
}
define void @vec_cttz_i32_neg(i32* %a, i32* %b, i32* %c, i1) {
; CHECK-LABEL: @vec_cttz_i32_neg(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[I0:%.*]] = load i32, i32* [[A:%.*]], align 4
; CHECK-NEXT: [[I1:%.*]] = load i32, i32* [[B:%.*]], align 4
; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[I0]], [[I1]]
; CHECK-NEXT: [[CALL1:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[ADD1]], i1 true) #[[ATTR3]]
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 1
; CHECK-NEXT: [[I2:%.*]] = load i32, i32* [[ARRAYIDX2]], align 4
; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 1
; CHECK-NEXT: [[I3:%.*]] = load i32, i32* [[ARRAYIDX3]], align 4
; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[I2]], [[I3]]
; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[ADD2]], i1 false) #[[ATTR3]]
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 2
; CHECK-NEXT: [[I4:%.*]] = load i32, i32* [[ARRAYIDX4]], align 4
; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 2
; CHECK-NEXT: [[I5:%.*]] = load i32, i32* [[ARRAYIDX5]], align 4
; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[I4]], [[I5]]
; CHECK-NEXT: [[CALL3:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[ADD3]], i1 true) #[[ATTR3]]
; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 3
; CHECK-NEXT: [[I6:%.*]] = load i32, i32* [[ARRAYIDX6]], align 4
; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 3
; CHECK-NEXT: [[I7:%.*]] = load i32, i32* [[ARRAYIDX7]], align 4
; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[I6]], [[I7]]
; CHECK-NEXT: [[CALL4:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[ADD4]], i1 false) #[[ATTR3]]
; CHECK-NEXT: store i32 [[CALL1]], i32* [[C:%.*]], align 4
; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i32, i32* [[C]], i32 1
; CHECK-NEXT: store i32 [[CALL2]], i32* [[ARRAYIDX8]], align 4
; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i32, i32* [[C]], i32 2
; CHECK-NEXT: store i32 [[CALL3]], i32* [[ARRAYIDX9]], align 4
; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds i32, i32* [[C]], i32 3
; CHECK-NEXT: store i32 [[CALL4]], i32* [[ARRAYIDX10]], align 4
; CHECK-NEXT: ret void
;
entry:
%i0 = load i32, i32* %a, align 4
%i1 = load i32, i32* %b, align 4
%add1 = add i32 %i0, %i1
%call1 = tail call i32 @llvm.cttz.i32(i32 %add1,i1 true) nounwind readnone
%arrayidx2 = getelementptr inbounds i32, i32* %a, i32 1
%i2 = load i32, i32* %arrayidx2, align 4
%arrayidx3 = getelementptr inbounds i32, i32* %b, i32 1
%i3 = load i32, i32* %arrayidx3, align 4
%add2 = add i32 %i2, %i3
%call2 = tail call i32 @llvm.cttz.i32(i32 %add2,i1 false) nounwind readnone
%arrayidx4 = getelementptr inbounds i32, i32* %a, i32 2
%i4 = load i32, i32* %arrayidx4, align 4
%arrayidx5 = getelementptr inbounds i32, i32* %b, i32 2
%i5 = load i32, i32* %arrayidx5, align 4
%add3 = add i32 %i4, %i5
%call3 = tail call i32 @llvm.cttz.i32(i32 %add3,i1 true) nounwind readnone
%arrayidx6 = getelementptr inbounds i32, i32* %a, i32 3
%i6 = load i32, i32* %arrayidx6, align 4
%arrayidx7 = getelementptr inbounds i32, i32* %b, i32 3
%i7 = load i32, i32* %arrayidx7, align 4
%add4 = add i32 %i6, %i7
%call4 = tail call i32 @llvm.cttz.i32(i32 %add4,i1 false) nounwind readnone
store i32 %call1, i32* %c, align 4
%arrayidx8 = getelementptr inbounds i32, i32* %c, i32 1
store i32 %call2, i32* %arrayidx8, align 4
%arrayidx9 = getelementptr inbounds i32, i32* %c, i32 2
store i32 %call3, i32* %arrayidx9, align 4
%arrayidx10 = getelementptr inbounds i32, i32* %c, i32 3
store i32 %call4, i32* %arrayidx10, align 4
ret void
}
declare float @llvm.powi.f32.i32(float, i32)
define void @vec_powi_f32(float* %a, float* %b, float* %c, i32 %P) {
; CHECK-LABEL: @vec_powi_f32(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = bitcast float* [[A:%.*]] to <4 x float>*
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, <4 x float>* [[TMP0]], align 4
; CHECK-NEXT: [[TMP2:%.*]] = bitcast float* [[B:%.*]] to <4 x float>*
; CHECK-NEXT: [[TMP3:%.*]] = load <4 x float>, <4 x float>* [[TMP2]], align 4
; CHECK-NEXT: [[TMP4:%.*]] = fadd <4 x float> [[TMP1]], [[TMP3]]
; CHECK-NEXT: [[TMP5:%.*]] = call <4 x float> @llvm.powi.v4f32.i32(<4 x float> [[TMP4]], i32 [[P:%.*]])
; CHECK-NEXT: [[TMP6:%.*]] = bitcast float* [[C:%.*]] to <4 x float>*
; CHECK-NEXT: store <4 x float> [[TMP5]], <4 x float>* [[TMP6]], align 4
; CHECK-NEXT: ret void
;
entry:
%i0 = load float, float* %a, align 4
%i1 = load float, float* %b, align 4
%add1 = fadd float %i0, %i1
%call1 = tail call float @llvm.powi.f32.i32(float %add1,i32 %P) nounwind readnone
%arrayidx2 = getelementptr inbounds float, float* %a, i32 1
%i2 = load float, float* %arrayidx2, align 4
%arrayidx3 = getelementptr inbounds float, float* %b, i32 1
%i3 = load float, float* %arrayidx3, align 4
%add2 = fadd float %i2, %i3
%call2 = tail call float @llvm.powi.f32.i32(float %add2,i32 %P) nounwind readnone
%arrayidx4 = getelementptr inbounds float, float* %a, i32 2
%i4 = load float, float* %arrayidx4, align 4
%arrayidx5 = getelementptr inbounds float, float* %b, i32 2
%i5 = load float, float* %arrayidx5, align 4
%add3 = fadd float %i4, %i5
%call3 = tail call float @llvm.powi.f32.i32(float %add3,i32 %P) nounwind readnone
%arrayidx6 = getelementptr inbounds float, float* %a, i32 3
%i6 = load float, float* %arrayidx6, align 4
%arrayidx7 = getelementptr inbounds float, float* %b, i32 3
%i7 = load float, float* %arrayidx7, align 4
%add4 = fadd float %i6, %i7
%call4 = tail call float @llvm.powi.f32.i32(float %add4,i32 %P) nounwind readnone
store float %call1, float* %c, align 4
%arrayidx8 = getelementptr inbounds float, float* %c, i32 1
store float %call2, float* %arrayidx8, align 4
%arrayidx9 = getelementptr inbounds float, float* %c, i32 2
store float %call3, float* %arrayidx9, align 4
%arrayidx10 = getelementptr inbounds float, float* %c, i32 3
store float %call4, float* %arrayidx10, align 4
ret void
}
define void @vec_powi_f32_neg(float* %a, float* %b, float* %c, i32 %P, i32 %Q) {
; CHECK-LABEL: @vec_powi_f32_neg(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[I0:%.*]] = load float, float* [[A:%.*]], align 4
; CHECK-NEXT: [[I1:%.*]] = load float, float* [[B:%.*]], align 4
; CHECK-NEXT: [[ADD1:%.*]] = fadd float [[I0]], [[I1]]
; CHECK-NEXT: [[CALL1:%.*]] = tail call float @llvm.powi.f32.i32(float [[ADD1]], i32 [[P:%.*]]) #[[ATTR3]]
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, float* [[A]], i32 1
; CHECK-NEXT: [[I2:%.*]] = load float, float* [[ARRAYIDX2]], align 4
; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, float* [[B]], i32 1
; CHECK-NEXT: [[I3:%.*]] = load float, float* [[ARRAYIDX3]], align 4
; CHECK-NEXT: [[ADD2:%.*]] = fadd float [[I2]], [[I3]]
; CHECK-NEXT: [[CALL2:%.*]] = tail call float @llvm.powi.f32.i32(float [[ADD2]], i32 [[Q:%.*]]) #[[ATTR3]]
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, float* [[A]], i32 2
; CHECK-NEXT: [[I4:%.*]] = load float, float* [[ARRAYIDX4]], align 4
; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, float* [[B]], i32 2
; CHECK-NEXT: [[I5:%.*]] = load float, float* [[ARRAYIDX5]], align 4
; CHECK-NEXT: [[ADD3:%.*]] = fadd float [[I4]], [[I5]]
; CHECK-NEXT: [[CALL3:%.*]] = tail call float @llvm.powi.f32.i32(float [[ADD3]], i32 [[P]]) #[[ATTR3]]
; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, float* [[A]], i32 3
; CHECK-NEXT: [[I6:%.*]] = load float, float* [[ARRAYIDX6]], align 4
; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, float* [[B]], i32 3
; CHECK-NEXT: [[I7:%.*]] = load float, float* [[ARRAYIDX7]], align 4
; CHECK-NEXT: [[ADD4:%.*]] = fadd float [[I6]], [[I7]]
; CHECK-NEXT: [[CALL4:%.*]] = tail call float @llvm.powi.f32.i32(float [[ADD4]], i32 [[Q]]) #[[ATTR3]]
; CHECK-NEXT: store float [[CALL1]], float* [[C:%.*]], align 4
; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, float* [[C]], i32 1
; CHECK-NEXT: store float [[CALL2]], float* [[ARRAYIDX8]], align 4
; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float* [[C]], i32 2
; CHECK-NEXT: store float [[CALL3]], float* [[ARRAYIDX9]], align 4
; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, float* [[C]], i32 3
; CHECK-NEXT: store float [[CALL4]], float* [[ARRAYIDX10]], align 4
; CHECK-NEXT: ret void
;
entry:
%i0 = load float, float* %a, align 4
%i1 = load float, float* %b, align 4
%add1 = fadd float %i0, %i1
%call1 = tail call float @llvm.powi.f32.i32(float %add1,i32 %P) nounwind readnone
%arrayidx2 = getelementptr inbounds float, float* %a, i32 1
%i2 = load float, float* %arrayidx2, align 4
%arrayidx3 = getelementptr inbounds float, float* %b, i32 1
%i3 = load float, float* %arrayidx3, align 4
%add2 = fadd float %i2, %i3
%call2 = tail call float @llvm.powi.f32.i32(float %add2,i32 %Q) nounwind readnone
%arrayidx4 = getelementptr inbounds float, float* %a, i32 2
%i4 = load float, float* %arrayidx4, align 4
%arrayidx5 = getelementptr inbounds float, float* %b, i32 2
%i5 = load float, float* %arrayidx5, align 4
%add3 = fadd float %i4, %i5
%call3 = tail call float @llvm.powi.f32.i32(float %add3,i32 %P) nounwind readnone
%arrayidx6 = getelementptr inbounds float, float* %a, i32 3
%i6 = load float, float* %arrayidx6, align 4
%arrayidx7 = getelementptr inbounds float, float* %b, i32 3
%i7 = load float, float* %arrayidx7, align 4
%add4 = fadd float %i6, %i7
%call4 = tail call float @llvm.powi.f32.i32(float %add4,i32 %Q) nounwind readnone
store float %call1, float* %c, align 4
%arrayidx8 = getelementptr inbounds float, float* %c, i32 1
store float %call2, float* %arrayidx8, align 4
%arrayidx9 = getelementptr inbounds float, float* %c, i32 2
store float %call3, float* %arrayidx9, align 4
%arrayidx10 = getelementptr inbounds float, float* %c, i32 3
store float %call4, float* %arrayidx10, align 4
ret void
}