blob: 3e02fc4e8b93ba619468120deda5de7bf2f3513f [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s
define void @idom_sign_bit_check_edge_dominates(i64 %a) {
; CHECK-LABEL: @idom_sign_bit_check_edge_dominates(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
; CHECK: land.lhs.true:
; CHECK-NEXT: br label [[LOR_END:%.*]]
; CHECK: lor.rhs:
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i64 [[A]], 0
; CHECK-NEXT: br i1 [[CMP2]], label [[LOR_END]], label [[LAND_RHS:%.*]]
; CHECK: land.rhs:
; CHECK-NEXT: br label [[LOR_END]]
; CHECK: lor.end:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp slt i64 %a, 0
br i1 %cmp, label %land.lhs.true, label %lor.rhs
land.lhs.true:
br label %lor.end
lor.rhs:
%cmp2 = icmp sgt i64 %a, 0
br i1 %cmp2, label %land.rhs, label %lor.end
land.rhs:
br label %lor.end
lor.end:
ret void
}
define void @idom_sign_bit_check_edge_not_dominates(i64 %a) {
; CHECK-LABEL: @idom_sign_bit_check_edge_not_dominates(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
; CHECK: land.lhs.true:
; CHECK-NEXT: br i1 undef, label [[LOR_END:%.*]], label [[LOR_RHS]]
; CHECK: lor.rhs:
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[A]], 0
; CHECK-NEXT: br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]
; CHECK: land.rhs:
; CHECK-NEXT: br label [[LOR_END]]
; CHECK: lor.end:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp slt i64 %a, 0
br i1 %cmp, label %land.lhs.true, label %lor.rhs
land.lhs.true:
br i1 undef, label %lor.end, label %lor.rhs
lor.rhs:
%cmp2 = icmp sgt i64 %a, 0
br i1 %cmp2, label %land.rhs, label %lor.end
land.rhs:
br label %lor.end
lor.end:
ret void
}
define void @idom_sign_bit_check_edge_dominates_select(i64 %a, i64 %b) {
; CHECK-LABEL: @idom_sign_bit_check_edge_dominates_select(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 5
; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
; CHECK: land.lhs.true:
; CHECK-NEXT: br label [[LOR_END:%.*]]
; CHECK: lor.rhs:
; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i64 [[A]], [[B:%.*]]
; CHECK-NEXT: br i1 [[CMP3]], label [[LOR_END]], label [[LAND_RHS:%.*]]
; CHECK: land.rhs:
; CHECK-NEXT: br label [[LOR_END]]
; CHECK: lor.end:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp slt i64 %a, 5
br i1 %cmp, label %land.lhs.true, label %lor.rhs
land.lhs.true:
br label %lor.end
lor.rhs:
%cmp2 = icmp sgt i64 %a, 5
%select = select i1 %cmp2, i64 %a, i64 5
%cmp3 = icmp ne i64 %select, %b
br i1 %cmp3, label %land.rhs, label %lor.end
land.rhs:
br label %lor.end
lor.end:
ret void
}
define void @idom_zbranch(i64 %a) {
; CHECK-LABEL: @idom_zbranch(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[A:%.*]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[LOR_END:%.*]], label [[LOR_RHS:%.*]]
; CHECK: lor.rhs:
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[A]], 0
; CHECK-NEXT: br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]
; CHECK: land.rhs:
; CHECK-NEXT: br label [[LOR_END]]
; CHECK: lor.end:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp sgt i64 %a, 0
br i1 %cmp, label %lor.end, label %lor.rhs
lor.rhs:
%cmp2 = icmp slt i64 %a, 0
br i1 %cmp2, label %land.rhs, label %lor.end
land.rhs:
br label %lor.end
lor.end:
ret void
}
define void @idom_not_zbranch(i32 %a, i32 %b) {
; CHECK-LABEL: @idom_not_zbranch(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[IF_END:%.*]]
; CHECK: if.end:
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], [[B:%.*]]
; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN]], label [[IF_THEN3:%.*]]
; CHECK: if.then3:
; CHECK-NEXT: br label [[RETURN]]
; CHECK: return:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp sgt i32 %a, 0
br i1 %cmp, label %return, label %if.end
if.end:
%cmp1 = icmp slt i32 %a, 0
%a. = select i1 %cmp1, i32 %a, i32 0
%cmp2 = icmp ne i32 %a., %b
br i1 %cmp2, label %if.then3, label %return
if.then3:
br label %return
return:
ret void
}
define void @trueblock_cmp_eq(i32 %a, i32 %b) {
; CHECK-LABEL: @trueblock_cmp_eq(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[IF_END:%.*]], label [[RETURN:%.*]]
; CHECK: if.end:
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], 1
; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN3:%.*]], label [[RETURN]]
; CHECK: if.then3:
; CHECK-NEXT: br label [[RETURN]]
; CHECK: return:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp sgt i32 %a, 0
br i1 %cmp, label %if.end, label %return
if.end:
%cmp1 = icmp slt i32 %a, 2
br i1 %cmp1, label %if.then3, label %return
if.then3:
br label %return
return:
ret void
}
define i1 @trueblock_cmp_is_false(i32 %x, i32 %y) {
; CHECK-LABEL: @trueblock_cmp_is_false(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
; CHECK: t:
; CHECK-NEXT: ret i1 false
; CHECK: f:
; CHECK-NEXT: ret i1 [[CMP]]
;
entry:
%cmp = icmp sgt i32 %x, %y
br i1 %cmp, label %t, label %f
t:
%cmp2 = icmp slt i32 %x, %y
ret i1 %cmp2
f:
ret i1 %cmp
}
define i1 @trueblock_cmp_is_false_commute(i32 %x, i32 %y) {
; CHECK-LABEL: @trueblock_cmp_is_false_commute(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
; CHECK: t:
; CHECK-NEXT: ret i1 false
; CHECK: f:
; CHECK-NEXT: ret i1 [[CMP]]
;
entry:
%cmp = icmp eq i32 %x, %y
br i1 %cmp, label %t, label %f
t:
%cmp2 = icmp sgt i32 %y, %x
ret i1 %cmp2
f:
ret i1 %cmp
}
define i1 @trueblock_cmp_is_true(i32 %x, i32 %y) {
; CHECK-LABEL: @trueblock_cmp_is_true(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
; CHECK: t:
; CHECK-NEXT: ret i1 true
; CHECK: f:
; CHECK-NEXT: ret i1 [[CMP]]
;
entry:
%cmp = icmp ult i32 %x, %y
br i1 %cmp, label %t, label %f
t:
%cmp2 = icmp ne i32 %x, %y
ret i1 %cmp2
f:
ret i1 %cmp
}
define i1 @trueblock_cmp_is_true_commute(i32 %x, i32 %y) {
; CHECK-LABEL: @trueblock_cmp_is_true_commute(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
; CHECK: t:
; CHECK-NEXT: ret i1 true
; CHECK: f:
; CHECK-NEXT: ret i1 [[CMP]]
;
entry:
%cmp = icmp ugt i32 %x, %y
br i1 %cmp, label %t, label %f
t:
%cmp2 = icmp ne i32 %y, %x
ret i1 %cmp2
f:
ret i1 %cmp
}
define i1 @falseblock_cmp_is_false(i32 %x, i32 %y) {
; CHECK-LABEL: @falseblock_cmp_is_false(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
; CHECK: t:
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK: f:
; CHECK-NEXT: ret i1 false
;
entry:
%cmp = icmp sle i32 %x, %y
br i1 %cmp, label %t, label %f
t:
ret i1 %cmp
f:
%cmp2 = icmp slt i32 %x, %y
ret i1 %cmp2
}
define i1 @falseblock_cmp_is_false_commute(i32 %x, i32 %y) {
; CHECK-LABEL: @falseblock_cmp_is_false_commute(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
; CHECK: t:
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK: f:
; CHECK-NEXT: ret i1 false
;
entry:
%cmp = icmp eq i32 %x, %y
br i1 %cmp, label %t, label %f
t:
ret i1 %cmp
f:
%cmp2 = icmp eq i32 %y, %x
ret i1 %cmp2
}
define i1 @falseblock_cmp_is_true(i32 %x, i32 %y) {
; CHECK-LABEL: @falseblock_cmp_is_true(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
; CHECK: t:
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK: f:
; CHECK-NEXT: ret i1 true
;
entry:
%cmp = icmp ult i32 %x, %y
br i1 %cmp, label %t, label %f
t:
ret i1 %cmp
f:
%cmp2 = icmp uge i32 %x, %y
ret i1 %cmp2
}
define i1 @falseblock_cmp_is_true_commute(i32 %x, i32 %y) {
; CHECK-LABEL: @falseblock_cmp_is_true_commute(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
; CHECK: t:
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK: f:
; CHECK-NEXT: ret i1 true
;
entry:
%cmp = icmp sgt i32 %x, %y
br i1 %cmp, label %t, label %f
t:
ret i1 %cmp
f:
%cmp2 = icmp sge i32 %y, %x
ret i1 %cmp2
}