@@ -1084,3 +1084,72 @@ define i8 @fshl_range_trunc(i1 %x) {
1084
1084
%tr = trunc nsw i32 %fshl to i8
1085
1085
ret i8 %tr
1086
1086
}
1087
+
1088
+ ;; Issue #138334 negative rotate amounts can be folded into the opposite direction
1089
+ define i32 @fshl_neg_amount (i32 %x , i32 %y ) {
1090
+ ; CHECK-LABEL: @fshl_neg_amount(
1091
+ ; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
1092
+ ; CHECK-NEXT: ret i32 [[R]]
1093
+ ;
1094
+ %n = sub i32 0 , %y
1095
+ %r = call i32 @llvm.fshl.i32 (i32 %x , i32 %x , i32 %n )
1096
+ ret i32 %r
1097
+ }
1098
+
1099
+ define i32 @fshr_neg_amount (i32 %x , i32 %y ) {
1100
+ ; CHECK-LABEL: @fshr_neg_amount(
1101
+ ; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
1102
+ ; CHECK-NEXT: ret i32 [[R]]
1103
+ ;
1104
+ %n = sub i32 0 , %y
1105
+ %r = call i32 @llvm.fshr.i32 (i32 %x , i32 %x , i32 %n )
1106
+ ret i32 %r
1107
+ }
1108
+
1109
+ ;; negative test, funnel shift is not a rotate
1110
+
1111
+ define i32 @fshl_neg_amount_non_rotate (i32 %x , i32 %y , i32 %z ) {
1112
+ ; CHECK-LABEL: @fshl_neg_amount_non_rotate(
1113
+ ; CHECK-NEXT: [[N:%.*]] = sub i32 0, [[Y:%.*]]
1114
+ ; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Z:%.*]], i32 [[N]])
1115
+ ; CHECK-NEXT: ret i32 [[R]]
1116
+ ;
1117
+ %n = sub i32 0 , %y
1118
+ %r = call i32 @llvm.fshl.i32 (i32 %x , i32 %z , i32 %n )
1119
+ ret i32 %r
1120
+ }
1121
+
1122
+ define i32 @fshr_neg_amount_non_rotate (i32 %x , i32 %y , i32 %z ) {
1123
+ ; CHECK-LABEL: @fshr_neg_amount_non_rotate(
1124
+ ; CHECK-NEXT: [[N:%.*]] = sub i32 0, [[Y:%.*]]
1125
+ ; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[Z:%.*]], i32 [[N]])
1126
+ ; CHECK-NEXT: ret i32 [[R]]
1127
+ ;
1128
+ %n = sub i32 0 , %y
1129
+ %r = call i32 @llvm.fshr.i32 (i32 %x , i32 %z , i32 %n )
1130
+ ret i32 %r
1131
+ }
1132
+
1133
+ ;; negative test, bitwidth is not a power of two
1134
+
1135
+ define i31 @fshl_neg_amount_non_power_two (i31 %x , i31 %y ) {
1136
+ ; CHECK-LABEL: @fshl_neg_amount_non_power_two(
1137
+ ; CHECK-NEXT: [[N:%.*]] = sub i31 0, [[Y:%.*]]
1138
+ ; CHECK-NEXT: [[R:%.*]] = call i31 @llvm.fshl.i31(i31 [[X:%.*]], i31 [[X]], i31 [[N]])
1139
+ ; CHECK-NEXT: ret i31 [[R]]
1140
+ ;
1141
+ %n = sub i31 0 , %y
1142
+ %r = call i31 @llvm.fshl.i31 (i31 %x , i31 %x , i31 %n )
1143
+ ret i31 %r
1144
+ }
1145
+
1146
+ define i31 @fshr_neg_amount_non_power_two (i31 %x , i31 %y ) {
1147
+ ; CHECK-LABEL: @fshr_neg_amount_non_power_two(
1148
+ ; CHECK-NEXT: [[N:%.*]] = sub i31 0, [[Y:%.*]]
1149
+ ; CHECK-NEXT: [[R:%.*]] = call i31 @llvm.fshr.i31(i31 [[X:%.*]], i31 [[X]], i31 [[N]])
1150
+ ; CHECK-NEXT: ret i31 [[R]]
1151
+ ;
1152
+ %n = sub i31 0 , %y
1153
+ %r = call i31 @llvm.fshr.i31 (i31 %x , i31 %x , i31 %n )
1154
+ ret i31 %r
1155
+ }
0 commit comments