@@ -1004,10 +1004,13 @@ define <2 x i32> @and_splat_constant(<2 x i32> %x) {
1004
1004
ret <2 x i32 > %r
1005
1005
}
1006
1006
1007
+ ; AND does not fold to undef for undef operands, we cannot move it
1008
+ ; across a shuffle with undef masks.
1007
1009
define <4 x i16 > @and_constant_mask_undef (<4 x i16 > %add ) {
1008
1010
; CHECK-LABEL: @and_constant_mask_undef(
1009
1011
; CHECK-NEXT: entry:
1010
- ; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1012
+ ; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1013
+ ; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[SHUFFLE]], <i16 0, i16 0, i16 -1, i16 -1>
1011
1014
; CHECK-NEXT: ret <4 x i16> [[AND]]
1012
1015
;
1013
1016
entry:
@@ -1016,10 +1019,13 @@ entry:
1016
1019
ret <4 x i16 > %and
1017
1020
}
1018
1021
1022
+ ; AND does not fold to undef for undef operands, we cannot move it
1023
+ ; across a shuffle with undef masks.
1019
1024
define <4 x i16 > @and_constant_mask_undef_2 (<4 x i16 > %add ) {
1020
1025
; CHECK-LABEL: @and_constant_mask_undef_2(
1021
1026
; CHECK-NEXT: entry:
1022
- ; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 undef>
1027
+ ; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 undef>
1028
+ ; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[SHUFFLE]], <i16 -1, i16 -1, i16 -1, i16 0>
1023
1029
; CHECK-NEXT: ret <4 x i16> [[AND]]
1024
1030
;
1025
1031
entry:
@@ -1028,22 +1034,26 @@ entry:
1028
1034
ret <4 x i16 > %and
1029
1035
}
1030
1036
1037
+ ; FIXME: We should be able to move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.
1031
1038
define <4 x i16 > @and_constant_mask_undef_3 (<4 x i16 > %add ) {
1032
1039
; CHECK-LABEL: @and_constant_mask_undef_3(
1033
1040
; CHECK-NEXT: entry:
1034
- ; CHECK-NEXT: ret <4 x i16> <i16 0, i16 0, i16 0, i16 undef>
1041
+ ; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> undef, <4 x i32> <i32 0, i32 1, i32 1, i32 undef>
1042
+ ; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[SHUFFLE]], <i16 0, i16 0, i16 0, i16 -1>
1043
+ ; CHECK-NEXT: ret <4 x i16> [[AND]]
1035
1044
;
1036
1045
entry:
1037
1046
%shuffle = shufflevector <4 x i16 > %add , <4 x i16 > undef , <4 x i32 > <i32 0 , i32 1 , i32 1 , i32 undef >
1038
1047
%and = and <4 x i16 > %shuffle , <i16 0 , i16 0 , i16 0 , i16 -1 >
1039
1048
ret <4 x i16 > %and
1040
1049
}
1041
1050
1051
+ ; FIXME: We should be able to move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.
1042
1052
define <4 x i16 > @and_constant_mask_undef_4 (<4 x i16 > %add ) {
1043
1053
; CHECK-LABEL: @and_constant_mask_undef_4(
1044
1054
; CHECK-NEXT: entry:
1045
- ; CHECK-NEXT: [[TMP0 :%.*]] = and <4 x i16> [[ADD:%.*]], <i16 9, i16 20, i16 undef, i16 undef>
1046
- ; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[TMP0 ]], <4 x i16> undef, <4 x i32> <i32 0, i32 1, i32 1, i32 undef >
1055
+ ; CHECK-NEXT: [[SHUFFLE :%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> undef, <4 x i32> <i32 0, i32 1, i32 1, i32 undef>
1056
+ ; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[SHUFFLE ]], <i16 9, i16 20, i16 20, i16 -1 >
1047
1057
; CHECK-NEXT: ret <4 x i16> [[AND]]
1048
1058
;
1049
1059
entry:
@@ -1052,7 +1062,6 @@ entry:
1052
1062
ret <4 x i16 > %and
1053
1063
}
1054
1064
1055
-
1056
1065
define <4 x i16 > @and_constant_mask_not_undef (<4 x i16 > %add ) {
1057
1066
; CHECK-LABEL: @and_constant_mask_not_undef(
1058
1067
; CHECK-NEXT: entry:
@@ -1066,10 +1075,13 @@ entry:
1066
1075
ret <4 x i16 > %and
1067
1076
}
1068
1077
1078
+ ; OR does not fold to undef for undef operands, we cannot move it
1079
+ ; across a shuffle with undef masks.
1069
1080
define <4 x i16 > @or_constant_mask_undef (<4 x i16 > %in ) {
1070
1081
; CHECK-LABEL: @or_constant_mask_undef(
1071
1082
; CHECK-NEXT: entry:
1072
- ; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1083
+ ; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1084
+ ; CHECK-NEXT: [[OR:%.*]] = or <4 x i16> [[SHUFFLE]], <i16 -1, i16 -1, i16 0, i16 0>
1073
1085
; CHECK-NEXT: ret <4 x i16> [[OR]]
1074
1086
;
1075
1087
entry:
@@ -1078,10 +1090,13 @@ entry:
1078
1090
ret <4 x i16 > %or
1079
1091
}
1080
1092
1093
+ ; OR does not fold to undef for undef operands, we cannot move it
1094
+ ; across a shuffle with undef masks.
1081
1095
define <4 x i16 > @or_constant_mask_undef_2 (<4 x i16 > %in ) {
1082
1096
; CHECK-LABEL: @or_constant_mask_undef_2(
1083
1097
; CHECK-NEXT: entry:
1084
- ; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>
1098
+ ; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>
1099
+ ; CHECK-NEXT: [[OR:%.*]] = or <4 x i16> [[SHUFFLE]], <i16 -1, i16 0, i16 0, i16 -1>
1085
1100
; CHECK-NEXT: ret <4 x i16> [[OR]]
1086
1101
;
1087
1102
entry:
@@ -1090,22 +1105,26 @@ entry:
1090
1105
ret <4 x i16 > %or
1091
1106
}
1092
1107
1108
+ ; FIXME: We should be able to move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.
1093
1109
define <4 x i16 > @or_constant_mask_undef_3 (<4 x i16 > %in ) {
1094
1110
; CHECK-LABEL: @or_constant_mask_undef_3(
1095
1111
; CHECK-NEXT: entry:
1096
- ; CHECK-NEXT: ret <4 x i16> <i16 undef, i16 -1, i16 -1, i16 undef>
1112
+ ; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>
1113
+ ; CHECK-NEXT: [[OR:%.*]] = or <4 x i16> [[SHUFFLE]], <i16 0, i16 -1, i16 -1, i16 0>
1114
+ ; CHECK-NEXT: ret <4 x i16> [[OR]]
1097
1115
;
1098
1116
entry:
1099
1117
%shuffle = shufflevector <4 x i16 > %in , <4 x i16 > undef , <4 x i32 > <i32 undef , i32 1 , i32 1 , i32 undef >
1100
1118
%or = or <4 x i16 > %shuffle , <i16 0 , i16 -1 , i16 -1 , i16 0 >
1101
1119
ret <4 x i16 > %or
1102
1120
}
1103
1121
1122
+ ; FIXME: We should be able to move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.
1104
1123
define <4 x i16 > @or_constant_mask_undef_4 (<4 x i16 > %in ) {
1105
1124
; CHECK-LABEL: @or_constant_mask_undef_4(
1106
1125
; CHECK-NEXT: entry:
1107
- ; CHECK-NEXT: [[TMP0 :%.*]] = or <4 x i16> [[IN:%.*]], <i16 undef, i16 99, i16 undef, i16 undef>
1108
- ; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[TMP0 ]], <4 x i16> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef >
1126
+ ; CHECK-NEXT: [[SHUFFLE :%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>
1127
+ ; CHECK-NEXT: [[OR:%.*]] = or <4 x i16> [[SHUFFLE ]], <i16 0, i16 99, i16 99, i16 0 >
1109
1128
; CHECK-NEXT: ret <4 x i16> [[OR]]
1110
1129
;
1111
1130
entry:
@@ -1130,8 +1149,8 @@ entry:
1130
1149
define <4 x i16 > @shl_constant_mask_undef (<4 x i16 > %in ) {
1131
1150
; CHECK-LABEL: @shl_constant_mask_undef(
1132
1151
; CHECK-NEXT: entry:
1133
- ; CHECK-NEXT: [[TMP0 :%.*]] = shl <4 x i16> [[IN:%.*]], <i16 10, i16 0, i16 0, i16 0 >
1134
- ; CHECK-NEXT: [[SHL:%.*]] = shufflevector <4 x i16> [[TMP0 ]], <4 x i16> undef, <4 x i32> <i32 0, i32 undef, i32 1, i32 1 >
1152
+ ; CHECK-NEXT: [[SHUFFLE :%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> undef, <4 x i32> <i32 0, i32 undef, i32 1, i32 1 >
1153
+ ; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i16> [[SHUFFLE ]], <i16 10, i16 3, i16 0, i16 0 >
1135
1154
; CHECK-NEXT: ret <4 x i16> [[SHL]]
1136
1155
;
1137
1156
entry:
0 commit comments