define i32 @srem_constant_dividend_select_of_constants_divisor(i1 %b) {
; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor(
-; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3
-; CHECK-NEXT: [[R:%.*]] = srem i32 42, [[S]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i32 6, i32 0
; CHECK-NEXT: ret i32 [[R]]
;
%s = select i1 %b, i32 12, i32 -3
ret i32 %r
}
+; TODO: srem should still be replaced by select.
+
define i32 @srem_constant_dividend_select_of_constants_divisor_use(i1 %b) {
; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor_use(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3
ret i32 %r
}
+; Rem-by-0 is immediate UB, so select is simplified.
+
define i32 @srem_constant_dividend_select_of_constants_divisor_0_arm(i1 %b) {
; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor_0_arm(
; CHECK-NEXT: ret i32 6
ret i32 %r
}
+; negative test - not safe to speculate rem with variable divisor
+
define i32 @srem_constant_dividend_select_divisor1(i1 %b, i32 %x) {
; CHECK-LABEL: @srem_constant_dividend_select_divisor1(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 [[X:%.*]], i32 -3
ret i32 %r
}
+; negative test - not safe to speculate rem with variable divisor
+
define i32 @srem_constant_dividend_select_divisor2(i1 %b, i32 %x) {
; CHECK-LABEL: @srem_constant_dividend_select_divisor2(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 [[X:%.*]]
define <2 x i8> @srem_constant_dividend_select_of_constants_divisor_vec(i1 %b) {
; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor_vec(
-; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4>
-; CHECK-NEXT: [[R:%.*]] = srem <2 x i8> <i8 42, i8 -42>, [[S]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 6, i8 -2>, <2 x i8> <i8 2, i8 -2>
; CHECK-NEXT: ret <2 x i8> [[R]]
;
%s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4>
ret <2 x i8> %r
}
+; Rem-by-0 element is immediate UB, so select is simplified.
+
define <2 x i8> @srem_constant_dividend_select_of_constants_divisor_vec_ub1(i1 %b) {
; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor_vec_ub1(
; CHECK-NEXT: ret <2 x i8> <i8 2, i8 -2>
ret <2 x i8> %r
}
+; SMIN % -1 element is poison.
+
define <2 x i8> @srem_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) {
; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor_vec_ub2(
-; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1>
-; CHECK-NEXT: [[R:%.*]] = srem <2 x i8> <i8 42, i8 -128>, [[S]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 6, i8 -3>, <2 x i8> <i8 2, i8 poison>
; CHECK-NEXT: ret <2 x i8> [[R]]
;
%s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1>
ret <2 x i8> %r
}
+; negative test - must have constant dividend
+
define i32 @srem_select_of_constants_divisor(i1 %b, i32 %x) {
; CHECK-LABEL: @srem_select_of_constants_divisor(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3
define i32 @urem_constant_dividend_select_of_constants_divisor(i1 %b) {
; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor(
-; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3
-; CHECK-NEXT: [[R:%.*]] = urem i32 42, [[S]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i32 6, i32 42
; CHECK-NEXT: ret i32 [[R]]
;
%s = select i1 %b, i32 12, i32 -3
ret i32 %r
}
+; TODO: urem should still be replaced by select.
+
define i32 @urem_constant_dividend_select_of_constants_divisor_use(i1 %b) {
; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor_use(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3
ret i32 %r
}
+; Rem-by-0 is immediate UB, so select is simplified.
+
define i32 @urem_constant_dividend_select_of_constants_divisor_0_arm(i1 %b) {
; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor_0_arm(
; CHECK-NEXT: ret i32 6
ret i32 %r
}
+; negative test - not safe to speculate rem with variable divisor
+
define i32 @urem_constant_dividend_select_divisor1(i1 %b, i32 %x) {
; CHECK-LABEL: @urem_constant_dividend_select_divisor1(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 [[X:%.*]], i32 -3
ret i32 %r
}
+; negative test - not safe to speculate rem with variable divisor
+
define i32 @urem_constant_dividend_select_divisor2(i1 %b, i32 %x) {
; CHECK-LABEL: @urem_constant_dividend_select_divisor2(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 [[X:%.*]]
define <2 x i8> @urem_constant_dividend_select_of_constants_divisor_vec(i1 %b) {
; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor_vec(
-; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4>
-; CHECK-NEXT: [[R:%.*]] = urem <2 x i8> <i8 42, i8 -42>, [[S]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 6, i8 -42>, <2 x i8> <i8 42, i8 2>
; CHECK-NEXT: ret <2 x i8> [[R]]
;
%s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4>
ret <2 x i8> %r
}
+; Rem-by-0 element is immediate UB, so select is simplified.
+
define <2 x i8> @urem_constant_dividend_select_of_constants_divisor_vec_ub1(i1 %b) {
; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor_vec_ub1(
; CHECK-NEXT: ret <2 x i8> <i8 42, i8 2>
ret <2 x i8> %r
}
+; There's no unsigned equivalent to "SMIN % -1", so this is just the usual constant folding.
+
define <2 x i8> @urem_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) {
; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor_vec_ub2(
-; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1>
-; CHECK-NEXT: [[R:%.*]] = urem <2 x i8> <i8 42, i8 -128>, [[S]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 6, i8 -128>, <2 x i8> <i8 42, i8 -128>
; CHECK-NEXT: ret <2 x i8> [[R]]
;
%s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1>
ret <2 x i8> %r
}
+; negative test - must have constant dividend
+
define i32 @urem_select_of_constants_divisor(i1 %b, i32 %x) {
; CHECK-LABEL: @urem_select_of_constants_divisor(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3