Fold bitcast (select cond, val, const) -> select cond, (bitcast val), (bitcast const) Rocm device libs has an unfortunate amount of code that does bithacking on the sign bit of double values by casting to <2 x i32> and operating on the high element. This breaks value tracking optimizations on the fp value. The existing transform would only do this if the input to the select was also a bitcast with a single use, and if it didn't convert between vector and scalar.
130 lines
6.8 KiB
LLVM
130 lines
6.8 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
|
|
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
|
|
|
|
define double @bitcast_v2i32_select_to_double_const_rhs(double %i, <2 x i32> %i41) {
|
|
; CHECK-LABEL: define double @bitcast_v2i32_select_to_double_const_rhs(
|
|
; CHECK-SAME: double [[I:%.*]], <2 x i32> [[I41:%.*]]) {
|
|
; CHECK-NEXT: [[I42:%.*]] = fcmp one double [[I]], 0x7FF0000000000000
|
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[I41]] to double
|
|
; CHECK-NEXT: [[ASTYPE13_I_I:%.*]] = select i1 [[I42]], double [[TMP1]], double 0x7FF8000000000000
|
|
; CHECK-NEXT: ret double [[ASTYPE13_I_I]]
|
|
;
|
|
%i42 = fcmp one double %i, 0x7FF0000000000000
|
|
%s.0.i.i = select i1 %i42, <2 x i32> %i41, <2 x i32> <i32 0, i32 2146959360>
|
|
%astype13.i.i = bitcast <2 x i32> %s.0.i.i to double
|
|
ret double %astype13.i.i
|
|
}
|
|
|
|
define double @bitcast_v2i32_select_to_double_const_lhs(double %i, <2 x i32> %i41) {
|
|
; CHECK-LABEL: define double @bitcast_v2i32_select_to_double_const_lhs(
|
|
; CHECK-SAME: double [[I:%.*]], <2 x i32> [[I41:%.*]]) {
|
|
; CHECK-NEXT: [[I42:%.*]] = fcmp one double [[I]], 0x7FF0000000000000
|
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[I41]] to double
|
|
; CHECK-NEXT: [[ASTYPE13_I_I:%.*]] = select i1 [[I42]], double 0x7FF8000000000000, double [[TMP1]]
|
|
; CHECK-NEXT: ret double [[ASTYPE13_I_I]]
|
|
;
|
|
%i42 = fcmp one double %i, 0x7FF0000000000000
|
|
%s.0.i.i = select i1 %i42, <2 x i32> <i32 0, i32 2146959360>, <2 x i32> %i41
|
|
%astype13.i.i = bitcast <2 x i32> %s.0.i.i to double
|
|
ret double %astype13.i.i
|
|
}
|
|
|
|
define <2 x i32> @bitcast_select_double_to_v2i32_const_rhs(i64 %i, double %i41) {
|
|
; CHECK-LABEL: define <2 x i32> @bitcast_select_double_to_v2i32_const_rhs(
|
|
; CHECK-SAME: i64 [[I:%.*]], double [[I41:%.*]]) {
|
|
; CHECK-NEXT: [[I42_NOT:%.*]] = icmp eq i64 [[I]], 0
|
|
; CHECK-NEXT: [[S_0_I_I:%.*]] = select nnan i1 [[I42_NOT]], double 1.000000e+00, double [[I41]]
|
|
; CHECK-NEXT: [[ASTYPE13_I_I:%.*]] = bitcast double [[S_0_I_I]] to <2 x i32>
|
|
; CHECK-NEXT: ret <2 x i32> [[ASTYPE13_I_I]]
|
|
;
|
|
%i42 = icmp ne i64 %i, 0
|
|
%s.0.i.i = select nnan i1 %i42, double %i41, double 1.0
|
|
%astype13.i.i = bitcast double %s.0.i.i to <2 x i32>
|
|
ret <2 x i32> %astype13.i.i
|
|
}
|
|
|
|
define <2 x i32> @bitcast_select_double_to_v2i32_const_lhs(i64 %i, double %i41) {
|
|
; CHECK-LABEL: define <2 x i32> @bitcast_select_double_to_v2i32_const_lhs(
|
|
; CHECK-SAME: i64 [[I:%.*]], double [[I41:%.*]]) {
|
|
; CHECK-NEXT: [[I42_NOT:%.*]] = icmp eq i64 [[I]], 0
|
|
; CHECK-NEXT: [[S_0_I_I:%.*]] = select nnan i1 [[I42_NOT]], double [[I41]], double 1.000000e+00
|
|
; CHECK-NEXT: [[ASTYPE13_I_I:%.*]] = bitcast double [[S_0_I_I]] to <2 x i32>
|
|
; CHECK-NEXT: ret <2 x i32> [[ASTYPE13_I_I]]
|
|
;
|
|
%i42 = icmp ne i64 %i, 0
|
|
%s.0.i.i = select nnan i1 %i42, double 1.0, double %i41
|
|
%astype13.i.i = bitcast double %s.0.i.i to <2 x i32>
|
|
ret <2 x i32> %astype13.i.i
|
|
}
|
|
|
|
; Negative test, don't do for vselect
|
|
define double @bitcast_v2i32_vselect_to_double_const_rhs(<2 x double> %cmp.vec, <2 x i32> %val) {
|
|
; CHECK-LABEL: define double @bitcast_v2i32_vselect_to_double_const_rhs(
|
|
; CHECK-SAME: <2 x double> [[CMP_VEC:%.*]], <2 x i32> [[VAL:%.*]]) {
|
|
; CHECK-NEXT: [[VCMP:%.*]] = fcmp one <2 x double> [[CMP_VEC]], splat (double 0x7FF0000000000000)
|
|
; CHECK-NEXT: [[S_0_I_I:%.*]] = select <2 x i1> [[VCMP]], <2 x i32> [[VAL]], <2 x i32> <i32 0, i32 2146959360>
|
|
; CHECK-NEXT: [[ASTYPE13_I_I:%.*]] = bitcast <2 x i32> [[S_0_I_I]] to double
|
|
; CHECK-NEXT: ret double [[ASTYPE13_I_I]]
|
|
;
|
|
%vcmp = fcmp one <2 x double> %cmp.vec, splat (double 0x7FF0000000000000)
|
|
%select = select <2 x i1> %vcmp, <2 x i32> %val, <2 x i32> <i32 0, i32 2146959360>
|
|
%cast = bitcast <2 x i32> %select to double
|
|
ret double %cast
|
|
}
|
|
|
|
define <2 x float> @bitcast_v4i16_select_to_v2f32_const_lhs(double %arg, <4 x i16> %vec.v4i16) {
|
|
; CHECK-LABEL: define <2 x float> @bitcast_v4i16_select_to_v2f32_const_lhs(
|
|
; CHECK-SAME: double [[ARG:%.*]], <4 x i16> [[VEC_V4I16:%.*]]) {
|
|
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double [[ARG]], 0x7FF0000000000000
|
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[VEC_V4I16]] to <2 x float>
|
|
; CHECK-NEXT: [[ASTYPE13_I_I:%.*]] = select i1 [[CMP]], <2 x float> <float 0x4372A00000000000, float 0xB8B744E1E0000000>, <2 x float> [[TMP1]]
|
|
; CHECK-NEXT: ret <2 x float> [[ASTYPE13_I_I]]
|
|
;
|
|
%cmp = fcmp one double %arg, 0x7FF0000000000000
|
|
%select = select i1 %cmp, <4 x i16> <i16 0, i16 23445, i16 9999, i16 34234>, <4 x i16> %vec.v4i16
|
|
%astype13.i.i = bitcast <4 x i16> %select to <2 x float>
|
|
ret <2 x float> %astype13.i.i
|
|
}
|
|
|
|
define <2 x float> @bitcast_v4i16_select_to_v2f32_const_rhs(double %arg, <4 x i16> %vec.v4i16) {
|
|
; CHECK-LABEL: define <2 x float> @bitcast_v4i16_select_to_v2f32_const_rhs(
|
|
; CHECK-SAME: double [[ARG:%.*]], <4 x i16> [[VEC_V4I16:%.*]]) {
|
|
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double [[ARG]], 0x7FF0000000000000
|
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[VEC_V4I16]] to <2 x float>
|
|
; CHECK-NEXT: [[ASTYPE13_I_I:%.*]] = select i1 [[CMP]], <2 x float> [[TMP1]], <2 x float> <float 0x4372A00000000000, float 0xB8B744E1E0000000>
|
|
; CHECK-NEXT: ret <2 x float> [[ASTYPE13_I_I]]
|
|
;
|
|
%cmp = fcmp one double %arg, 0x7FF0000000000000
|
|
%select = select i1 %cmp, <4 x i16> %vec.v4i16, <4 x i16> <i16 0, i16 23445, i16 9999, i16 34234>
|
|
%astype13.i.i = bitcast <4 x i16> %select to <2 x float>
|
|
ret <2 x float> %astype13.i.i
|
|
}
|
|
|
|
define <2 x float> @bitcast_v2i32_select_to_v2f32_const_rhs(double %arg, <2 x i32> %vec) {
|
|
; CHECK-LABEL: define <2 x float> @bitcast_v2i32_select_to_v2f32_const_rhs(
|
|
; CHECK-SAME: double [[ARG:%.*]], <2 x i32> [[VEC:%.*]]) {
|
|
; CHECK-NEXT: [[I42:%.*]] = fcmp one double [[ARG]], 0x7FF0000000000000
|
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VEC]] to <2 x float>
|
|
; CHECK-NEXT: [[ASTYPE13_I_I:%.*]] = select i1 [[I42]], <2 x float> [[TMP1]], <2 x float> <float 0.000000e+00, float 0x7FFF000000000000>
|
|
; CHECK-NEXT: ret <2 x float> [[ASTYPE13_I_I]]
|
|
;
|
|
%cmp = fcmp one double %arg, 0x7FF0000000000000
|
|
%s.0.i.i = select i1 %cmp, <2 x i32> %vec, <2 x i32> <i32 0, i32 2146959360>
|
|
%astype13.i.i = bitcast <2 x i32> %s.0.i.i to <2 x float>
|
|
ret <2 x float> %astype13.i.i
|
|
}
|
|
|
|
define <2 x float> @bitcast_v2i32_select_to_v2f32_const_lhs(double %arg, <2 x i32> %vec) {
|
|
; CHECK-LABEL: define <2 x float> @bitcast_v2i32_select_to_v2f32_const_lhs(
|
|
; CHECK-SAME: double [[ARG:%.*]], <2 x i32> [[VEC:%.*]]) {
|
|
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double [[ARG]], 0x7FF0000000000000
|
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VEC]] to <2 x float>
|
|
; CHECK-NEXT: [[ASTYPE13_I_I:%.*]] = select i1 [[CMP]], <2 x float> <float 0.000000e+00, float 0x7FFF000000000000>, <2 x float> [[TMP1]]
|
|
; CHECK-NEXT: ret <2 x float> [[ASTYPE13_I_I]]
|
|
;
|
|
%cmp = fcmp one double %arg, 0x7FF0000000000000
|
|
%s.0.i.i = select i1 %cmp, <2 x i32> <i32 0, i32 2146959360>, <2 x i32> %vec
|
|
%astype13.i.i = bitcast <2 x i32> %s.0.i.i to <2 x float>
|
|
ret <2 x float> %astype13.i.i
|
|
}
|