blob: 42a89ab0dbc038ee2f111b807d3707cdab42604b [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
define i1 @infer_nuw(i8 range(i8 0, 2) %A, i8 range(i8 0, 2) %B) {
; CHECK-LABEL: define i1 @infer_nuw(
; CHECK-SAME: i8 range(i8 0, 2) [[A:%.*]], i8 range(i8 0, 2) [[B:%.*]]) {
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[B]], [[A]]
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i8 [[XOR]] to i1
; CHECK-NEXT: ret i1 [[TRUNC]]
;
%xor = xor i8 %B, %A
%trunc = trunc i8 %xor to i1
ret i1 %trunc
}
define i4 @infer_nsw(i8 %A) {
; CHECK-LABEL: define range(i4 -4, 4) i4 @infer_nsw(
; CHECK-SAME: i8 [[A:%.*]]) {
; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[A]], 5
; CHECK-NEXT: [[B:%.*]] = trunc nsw i8 [[ASHR]] to i4
; CHECK-NEXT: ret i4 [[B]]
;
%ashr = ashr i8 %A, 5
%result = trunc i8 %ashr to i4
ret i4 %result
}
define i8 @infer_nuw_nsw(i16 range(i16 -5, -3) %A, i16 range(i16 -5, -3) %B) {
; CHECK-LABEL: define range(i8 0, 8) i8 @infer_nuw_nsw(
; CHECK-SAME: i16 range(i16 -5, -3) [[A:%.*]], i16 range(i16 -5, -3) [[B:%.*]]) {
; CHECK-NEXT: [[XOR:%.*]] = xor i16 [[B]], [[A]]
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw nsw i16 [[XOR]] to i8
; CHECK-NEXT: ret i8 [[TRUNC]]
;
%xor = xor i16 %B, %A
%trunc = trunc i16 %xor to i8
ret i8 %trunc
}
define i8 @infer_nsw_from_assume(i16 %x) {
; CHECK-LABEL: define i8 @infer_nsw_from_assume(
; CHECK-SAME: i16 [[X:%.*]]) {
; CHECK-NEXT: [[ADD:%.*]] = add i16 [[X]], 128
; CHECK-NEXT: [[OR_COND_I:%.*]] = icmp ult i16 [[ADD]], 256
; CHECK-NEXT: tail call void @llvm.assume(i1 [[OR_COND_I]])
; CHECK-NEXT: [[CONV1:%.*]] = trunc nsw i16 [[X]] to i8
; CHECK-NEXT: ret i8 [[CONV1]]
;
%add = add i16 %x, 128
%or.cond.i = icmp ult i16 %add, 256
tail call void @llvm.assume(i1 %or.cond.i)
%conv1 = trunc i16 %x to i8
ret i8 %conv1
}
define i1 @rust_issue_122734(i8 range(i8 0, 3) %A, i8 range(i8 0, 3) %B) {
; CHECK-LABEL: define i1 @rust_issue_122734(
; CHECK-SAME: i8 range(i8 0, 3) [[A:%.*]], i8 range(i8 0, 3) [[B:%.*]]) {
; CHECK-NEXT: [[START:.*]]:
; CHECK-NEXT: [[LHS:%.*]] = icmp eq i8 [[A]], 2
; CHECK-NEXT: [[RHS:%.*]] = icmp eq i8 [[B]], 2
; CHECK-NEXT: [[OR:%.*]] = or i1 [[LHS]], [[RHS]]
; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[RHS]]
; CHECK-NEXT: br i1 [[OR]], label %[[IFTRUE:.*]], label %[[IFFALSE:.*]]
; CHECK: [[IFTRUE]]:
; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ [[XOR2:%.*]], %[[IFFALSE]] ], [ [[AND]], %[[START]] ]
; CHECK-NEXT: ret i1 [[PHI]]
; CHECK: [[IFFALSE]]:
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A]], [[B]]
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i8 [[XOR]] to i1
; CHECK-NEXT: [[XOR2]] = xor i1 [[TRUNC]], true
; CHECK-NEXT: br label %[[IFTRUE]]
;
start:
%lhs = icmp eq i8 %A, 2
%rhs = icmp eq i8 %B, 2
%or = or i1 %lhs, %rhs
%and = and i1 %lhs, %rhs
br i1 %or, label %iftrue, label %iffalse
iftrue:
%phi = phi i1 [ %xor2, %iffalse], [ %and, %start ]
ret i1 %phi
iffalse:
%xor = xor i8 %A, %B
%trunc = trunc i8 %xor to i1
%xor2 = xor i1 %trunc, true
br label %iftrue
}
define i1 @overdefined_range_negative(i8 %A, i8 %B) {
; CHECK-LABEL: define i1 @overdefined_range_negative(
; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A]], [[B]]
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[XOR]] to i1
; CHECK-NEXT: ret i1 [[TRUNC]]
;
%xor = xor i8 %A, %B
%trunc = trunc i8 %xor to i1
ret i1 %trunc
}
define i1 @trunc_nuw_infere_false_for_icmp_ne_1(i8 %x) {
; CHECK-LABEL: define i1 @trunc_nuw_infere_false_for_icmp_ne_1(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i8 [[X]], 1
; CHECK-NEXT: br i1 [[ICMP]], label %[[IFTRUE:.*]], label %[[IFFALSE:.*]]
; CHECK: [[IFTRUE]]:
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i8 [[X]] to i1
; CHECK-NEXT: ret i1 false
; CHECK: [[IFFALSE]]:
; CHECK-NEXT: ret i1 true
;
%icmp = icmp ne i8 %x, 1
br i1 %icmp, label %iftrue, label %iffalse
iftrue:
%trunc = trunc nuw i8 %x to i1
ret i1 %trunc
iffalse:
ret i1 true
}
define i1 @neg_trunc_do_not_infere_false_for_icmp_ne_1(i8 %x) {
; CHECK-LABEL: define i1 @neg_trunc_do_not_infere_false_for_icmp_ne_1(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i8 [[X]], 1
; CHECK-NEXT: br i1 [[ICMP]], label %[[IFTRUE:.*]], label %[[IFFALSE:.*]]
; CHECK: [[IFTRUE]]:
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[X]] to i1
; CHECK-NEXT: ret i1 [[TRUNC]]
; CHECK: [[IFFALSE]]:
; CHECK-NEXT: ret i1 true
;
%icmp = icmp ne i8 %x, 1
br i1 %icmp, label %iftrue, label %iffalse
iftrue:
%trunc = trunc i8 %x to i1
ret i1 %trunc
iffalse:
ret i1 true
}