ret i1 %r
}
+; Even if we don't have nsw, the range is still limited in the unsigned domain.
+define i1 @abs_positive_or_signed_min(i32 %x) {
+; CHECK-LABEL: @abs_positive_or_signed_min(
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
+; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
+; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
+; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[ABS]], -2147483647
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %cmp = icmp slt i32 %x, 0
+ %negx = sub i32 0, %x
+ %abs = select i1 %cmp, i32 %negx, i32 %x
+ %r = icmp ult i32 %abs, 2147483649
+ ret i1 %r
+}
+
+define i1 @abs_positive_or_signed_min_reduced_range(i32 %x) {
+; CHECK-LABEL: @abs_positive_or_signed_min_reduced_range(
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
+; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
+; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
+; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[ABS]], -2147483648
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %cmp = icmp slt i32 %x, 0
+ %negx = sub i32 0, %x
+ %abs = select i1 %cmp, i32 %negx, i32 %x
+ %r = icmp ult i32 %abs, 2147483648
+ ret i1 %r
+}
+
; This is canonical form for this IR. For nabs(), we don't require 'nsw'
define i1 @nabs_is_negative_or_0(i32 %x) {