233 lines
9.7 KiB
LLVM
233 lines
9.7 KiB
LLVM
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||
|
; RUN: opt -mtriple=armv7-apple-darwin < %s -codegenprepare -S | FileCheck -check-prefix=NEON %s
|
||
|
; RUN: opt -mtriple=armv6-unknown-linux < %s -codegenprepare -S | FileCheck -check-prefix=NONEON %s
|
||
|
|
||
|
define <8 x i16> @sink_zext(<8 x i8> %a, <8 x i8> %b, i1 %c) {
|
||
|
; NEON-LABEL: @sink_zext(
|
||
|
; NEON-NEXT: entry:
|
||
|
; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||
|
; NEON: if.then:
|
||
|
; NEON-NEXT: [[ZB_1:%.*]] = zext <8 x i8> [[B:%.*]] to <8 x i16>
|
||
|
; NEON-NEXT: [[TMP0:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
|
||
|
; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]
|
||
|
; NEON-NEXT: ret <8 x i16> [[RES_1]]
|
||
|
; NEON: if.else:
|
||
|
; NEON-NEXT: [[ZB_2:%.*]] = zext <8 x i8> [[B]] to <8 x i16>
|
||
|
; NEON-NEXT: [[TMP1:%.*]] = zext <8 x i8> [[A]] to <8 x i16>
|
||
|
; NEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[TMP1]], [[ZB_2]]
|
||
|
; NEON-NEXT: ret <8 x i16> [[RES_2]]
|
||
|
;
|
||
|
; NONEON-LABEL: @sink_zext(
|
||
|
; NONEON-NEXT: entry:
|
||
|
; NONEON-NEXT: [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
|
||
|
; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||
|
; NONEON: if.then:
|
||
|
; NONEON-NEXT: [[ZB_1:%.*]] = zext <8 x i8> [[B:%.*]] to <8 x i16>
|
||
|
; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[ZB_1]]
|
||
|
; NONEON-NEXT: ret <8 x i16> [[RES_1]]
|
||
|
; NONEON: if.else:
|
||
|
; NONEON-NEXT: [[ZB_2:%.*]] = zext <8 x i8> [[B]] to <8 x i16>
|
||
|
; NONEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[ZA]], [[ZB_2]]
|
||
|
; NONEON-NEXT: ret <8 x i16> [[RES_2]]
|
||
|
;
|
||
|
entry:
|
||
|
%za = zext <8 x i8> %a to <8 x i16>
|
||
|
br i1 %c, label %if.then, label %if.else
|
||
|
|
||
|
if.then:
|
||
|
%zb.1 = zext <8 x i8> %b to <8 x i16>
|
||
|
%res.1 = add <8 x i16> %za, %zb.1
|
||
|
ret <8 x i16> %res.1
|
||
|
|
||
|
if.else:
|
||
|
%zb.2 = zext <8 x i8> %b to <8 x i16>
|
||
|
%res.2 = sub <8 x i16> %za, %zb.2
|
||
|
ret <8 x i16> %res.2
|
||
|
}
|
||
|
|
||
|
define <8 x i16> @sink_sext(<8 x i8> %a, <8 x i8> %b, i1 %c) {
|
||
|
; NEON-LABEL: @sink_sext(
|
||
|
; NEON-NEXT: entry:
|
||
|
; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||
|
; NEON: if.then:
|
||
|
; NEON-NEXT: [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>
|
||
|
; NEON-NEXT: [[TMP0:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
|
||
|
; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]
|
||
|
; NEON-NEXT: ret <8 x i16> [[RES_1]]
|
||
|
; NEON: if.else:
|
||
|
; NEON-NEXT: [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>
|
||
|
; NEON-NEXT: [[TMP1:%.*]] = sext <8 x i8> [[A]] to <8 x i16>
|
||
|
; NEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[TMP1]], [[ZB_2]]
|
||
|
; NEON-NEXT: ret <8 x i16> [[RES_2]]
|
||
|
;
|
||
|
; NONEON-LABEL: @sink_sext(
|
||
|
; NONEON-NEXT: entry:
|
||
|
; NONEON-NEXT: [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
|
||
|
; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||
|
; NONEON: if.then:
|
||
|
; NONEON-NEXT: [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>
|
||
|
; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[ZB_1]]
|
||
|
; NONEON-NEXT: ret <8 x i16> [[RES_1]]
|
||
|
; NONEON: if.else:
|
||
|
; NONEON-NEXT: [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>
|
||
|
; NONEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[ZA]], [[ZB_2]]
|
||
|
; NONEON-NEXT: ret <8 x i16> [[RES_2]]
|
||
|
;
|
||
|
entry:
|
||
|
%za = sext <8 x i8> %a to <8 x i16>
|
||
|
br i1 %c, label %if.then, label %if.else
|
||
|
|
||
|
if.then:
|
||
|
%zb.1 = sext <8 x i8> %b to <8 x i16>
|
||
|
%res.1 = add <8 x i16> %za, %zb.1
|
||
|
ret <8 x i16> %res.1
|
||
|
|
||
|
if.else:
|
||
|
%zb.2 = sext <8 x i8> %b to <8 x i16>
|
||
|
%res.2 = sub <8 x i16> %za, %zb.2
|
||
|
ret <8 x i16> %res.2
|
||
|
}
|
||
|
|
||
|
define <8 x i16> @do_not_sink_nonfree_zext(<8 x i8> %a, <8 x i16> %b, i1 %c) {
|
||
|
;
|
||
|
; NEON-LABEL: @do_not_sink_nonfree_zext(
|
||
|
; NEON-NEXT: entry:
|
||
|
; NEON-NEXT: [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
|
||
|
; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||
|
; NEON: if.then:
|
||
|
; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
|
||
|
; NEON-NEXT: ret <8 x i16> [[RES_1]]
|
||
|
; NEON: if.else:
|
||
|
; NEON-NEXT: ret <8 x i16> [[B]]
|
||
|
;
|
||
|
; NONEON-LABEL: @do_not_sink_nonfree_zext(
|
||
|
; NONEON-NEXT: entry:
|
||
|
; NONEON-NEXT: [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
|
||
|
; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||
|
; NONEON: if.then:
|
||
|
; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
|
||
|
; NONEON-NEXT: ret <8 x i16> [[RES_1]]
|
||
|
; NONEON: if.else:
|
||
|
; NONEON-NEXT: ret <8 x i16> [[B]]
|
||
|
;
|
||
|
entry:
|
||
|
%za = zext <8 x i8> %a to <8 x i16>
|
||
|
br i1 %c, label %if.then, label %if.else
|
||
|
|
||
|
if.then:
|
||
|
%res.1 = add <8 x i16> %za, %b
|
||
|
ret <8 x i16> %res.1
|
||
|
|
||
|
if.else:
|
||
|
ret <8 x i16> %b
|
||
|
}
|
||
|
|
||
|
define <8 x i16> @do_not_sink_nonfree_sext(<8 x i8> %a, <8 x i16> %b, i1 %c) {
|
||
|
; CHECK-LABEL: @do_not_sink_nonfree_sext(
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||
|
; CHECK: if.then:
|
||
|
; CHECK-NEXT: [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>
|
||
|
; CHECK-NEXT: [[TMP0:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
|
||
|
; CHECK-NEXT: [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]
|
||
|
; CHECK-NEXT: ret <8 x i16> [[RES_1]]
|
||
|
; CHECK: if.else:
|
||
|
; CHECK-NEXT: [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>
|
||
|
; CHECK-NEXT: ret <8 x i16> [[ZB_2]]
|
||
|
;
|
||
|
; NEON-LABEL: @do_not_sink_nonfree_sext(
|
||
|
; NEON-NEXT: entry:
|
||
|
; NEON-NEXT: [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
|
||
|
; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||
|
; NEON: if.then:
|
||
|
; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
|
||
|
; NEON-NEXT: ret <8 x i16> [[RES_1]]
|
||
|
; NEON: if.else:
|
||
|
; NEON-NEXT: ret <8 x i16> [[B]]
|
||
|
;
|
||
|
; NONEON-LABEL: @do_not_sink_nonfree_sext(
|
||
|
; NONEON-NEXT: entry:
|
||
|
; NONEON-NEXT: [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
|
||
|
; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||
|
; NONEON: if.then:
|
||
|
; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
|
||
|
; NONEON-NEXT: ret <8 x i16> [[RES_1]]
|
||
|
; NONEON: if.else:
|
||
|
; NONEON-NEXT: ret <8 x i16> [[B]]
|
||
|
;
|
||
|
entry:
|
||
|
%za = sext <8 x i8> %a to <8 x i16>
|
||
|
br i1 %c, label %if.then, label %if.else
|
||
|
|
||
|
if.then:
|
||
|
%res.1 = add <8 x i16> %za, %b
|
||
|
ret <8 x i16> %res.1
|
||
|
|
||
|
if.else:
|
||
|
ret <8 x i16> %b
|
||
|
}
|
||
|
|
||
|
declare void @user1(<8 x i16>)
|
||
|
|
||
|
; Exts can be sunk.
|
||
|
define <8 x i16> @sink_shufflevector_ext_subadd_multiuse(<16 x i8> %a, <16 x i8> %b) {
|
||
|
; NEON-LABEL: @sink_shufflevector_ext_subadd_multiuse(
|
||
|
; NEON-NEXT: entry:
|
||
|
; NEON-NEXT: [[S1:%.*]] = shufflevector <16 x i8> [[A:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
||
|
; NEON-NEXT: [[S3:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
||
|
; NEON-NEXT: [[Z3:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>
|
||
|
; NEON-NEXT: call void @user1(<8 x i16> [[Z3]])
|
||
|
; NEON-NEXT: br i1 undef, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||
|
; NEON: if.then:
|
||
|
; NEON-NEXT: [[S2:%.*]] = shufflevector <16 x i8> [[B:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
||
|
; NEON-NEXT: [[Z2:%.*]] = zext <8 x i8> [[S2]] to <8 x i16>
|
||
|
; NEON-NEXT: [[TMP0:%.*]] = zext <8 x i8> [[S1]] to <8 x i16>
|
||
|
; NEON-NEXT: [[RES1:%.*]] = add <8 x i16> [[TMP0]], [[Z2]]
|
||
|
; NEON-NEXT: ret <8 x i16> [[RES1]]
|
||
|
; NEON: if.else:
|
||
|
; NEON-NEXT: [[S4:%.*]] = shufflevector <16 x i8> [[B]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
||
|
; NEON-NEXT: [[Z4:%.*]] = sext <8 x i8> [[S4]] to <8 x i16>
|
||
|
; NEON-NEXT: [[TMP1:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>
|
||
|
; NEON-NEXT: [[RES2:%.*]] = sub <8 x i16> [[TMP1]], [[Z4]]
|
||
|
; NEON-NEXT: ret <8 x i16> [[RES2]]
|
||
|
;
|
||
|
; NONEON-LABEL: @sink_shufflevector_ext_subadd_multiuse(
|
||
|
; NONEON-NEXT: entry:
|
||
|
; NONEON-NEXT: [[S1:%.*]] = shufflevector <16 x i8> [[A:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
||
|
; NONEON-NEXT: [[Z1:%.*]] = zext <8 x i8> [[S1]] to <8 x i16>
|
||
|
; NONEON-NEXT: [[S3:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
||
|
; NONEON-NEXT: [[Z3:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>
|
||
|
; NONEON-NEXT: call void @user1(<8 x i16> [[Z3]])
|
||
|
; NONEON-NEXT: br i1 undef, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||
|
; NONEON: if.then:
|
||
|
; NONEON-NEXT: [[S2:%.*]] = shufflevector <16 x i8> [[B:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
||
|
; NONEON-NEXT: [[Z2:%.*]] = zext <8 x i8> [[S2]] to <8 x i16>
|
||
|
; NONEON-NEXT: [[RES1:%.*]] = add <8 x i16> [[Z1]], [[Z2]]
|
||
|
; NONEON-NEXT: ret <8 x i16> [[RES1]]
|
||
|
; NONEON: if.else:
|
||
|
; NONEON-NEXT: [[S4:%.*]] = shufflevector <16 x i8> [[B]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
||
|
; NONEON-NEXT: [[Z4:%.*]] = sext <8 x i8> [[S4]] to <8 x i16>
|
||
|
; NONEON-NEXT: [[RES2:%.*]] = sub <8 x i16> [[Z3]], [[Z4]]
|
||
|
; NONEON-NEXT: ret <8 x i16> [[RES2]]
|
||
|
;
|
||
|
entry:
|
||
|
%s1 = shufflevector <16 x i8> %a, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
||
|
%z1 = zext <8 x i8> %s1 to <8 x i16>
|
||
|
%s3 = shufflevector <16 x i8> %a, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
||
|
%z3 = sext <8 x i8> %s3 to <8 x i16>
|
||
|
call void @user1(<8 x i16> %z3)
|
||
|
br i1 undef, label %if.then, label %if.else
|
||
|
|
||
|
if.then:
|
||
|
%s2 = shufflevector <16 x i8> %b, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
||
|
%z2 = zext <8 x i8> %s2 to <8 x i16>
|
||
|
%res1 = add <8 x i16> %z1, %z2
|
||
|
ret <8 x i16> %res1
|
||
|
|
||
|
if.else:
|
||
|
%s4 = shufflevector <16 x i8> %b, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
||
|
%z4 = sext <8 x i8> %s4 to <8 x i16>
|
||
|
%res2 = sub <8 x i16> %z3, %z4
|
||
|
ret <8 x i16> %res2
|
||
|
}
|