160 lines
5.6 KiB
LLVM
160 lines
5.6 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
|
|
|
define i1 @test(i1 %cond, i64 %left, i64 %right) {
|
|
; CHECK-LABEL: define i1 @test(
|
|
; CHECK-SAME: i1 [[COND:%.*]], i64 [[LEFT:%.*]], i64 [[RIGHT:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: br i1 [[COND]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
|
|
; CHECK: [[COND_TRUE]]:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[RIGHT]], [[LEFT]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label %[[END:.*]], label %[[COND_FALSE]]
|
|
; CHECK: [[COND_FALSE]]:
|
|
; CHECK-NEXT: br label %[[END]]
|
|
; CHECK: [[END]]:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
start:
|
|
br i1 %cond, label %cond.true, label %cond.false
|
|
|
|
cond.true:
|
|
%cmp = icmp sgt i64 %right, %left
|
|
br i1 %cmp, label %end, label %cond.false
|
|
|
|
cond.false:
|
|
%left_or_right = phi i64 [ %left, %start ], [ %right, %cond.true ]
|
|
%false = icmp sgt i64 %left_or_right, %left
|
|
br label %end
|
|
|
|
end:
|
|
%result = phi i1 [ false, %cond.true ], [ %false, %cond.false ]
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @test_commuted(i1 %cond, i64 %left, i64 %right) {
|
|
; CHECK-LABEL: define i1 @test_commuted(
|
|
; CHECK-SAME: i1 [[COND:%.*]], i64 [[LEFT:%.*]], i64 [[RIGHT:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: br i1 [[COND]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
|
|
; CHECK: [[COND_TRUE]]:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[RIGHT]], [[LEFT]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label %[[END:.*]], label %[[COND_FALSE]]
|
|
; CHECK: [[COND_FALSE]]:
|
|
; CHECK-NEXT: br label %[[END]]
|
|
; CHECK: [[END]]:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
start:
|
|
br i1 %cond, label %cond.true, label %cond.false
|
|
|
|
cond.true:
|
|
%cmp = icmp sgt i64 %right, %left
|
|
br i1 %cmp, label %end, label %cond.false
|
|
|
|
cond.false:
|
|
%left_or_right = phi i64 [ %left, %start ], [ %right, %cond.true ]
|
|
%false = icmp slt i64 %left, %left_or_right
|
|
br label %end
|
|
|
|
end:
|
|
%result = phi i1 [ false, %cond.true ], [ %false, %cond.false ]
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @test_with_wrong_icmp(i1 %cond, i64 %left, i64 %right) {
|
|
; CHECK-LABEL: define i1 @test_with_wrong_icmp(
|
|
; CHECK-SAME: i1 [[COND:%.*]], i64 [[LEFT:%.*]], i64 [[RIGHT:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*]]:
|
|
; CHECK-NEXT: br i1 [[COND]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
|
|
; CHECK: [[COND_TRUE]]:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[RIGHT]], [[LEFT]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label %[[END:.*]], label %[[COND_FALSE]]
|
|
; CHECK: [[COND_FALSE]]:
|
|
; CHECK-NEXT: [[LEFT_OR_RIGHT:%.*]] = phi i64 [ [[LEFT]], %[[START]] ], [ [[RIGHT]], %[[COND_TRUE]] ]
|
|
; CHECK-NEXT: [[FALSE:%.*]] = icmp sge i64 [[LEFT_OR_RIGHT]], [[LEFT]]
|
|
; CHECK-NEXT: br label %[[END]]
|
|
; CHECK: [[END]]:
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i1 [ false, %[[COND_TRUE]] ], [ [[FALSE]], %[[COND_FALSE]] ]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
br i1 %cond, label %cond.true, label %cond.false
|
|
|
|
cond.true:
|
|
%cmp = icmp sgt i64 %right, %left
|
|
br i1 %cmp, label %end, label %cond.false
|
|
|
|
cond.false:
|
|
%left_or_right = phi i64 [ %left, %start ], [ %right, %cond.true ]
|
|
%false = icmp sge i64 %left_or_right, %left
|
|
br label %end
|
|
|
|
end:
|
|
%result = phi i1 [ false, %cond.true ], [ %false, %cond.false ]
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @test_with_unfoldable_phi(i1 %cond, i64 %left, i64 %right) {
|
|
; CHECK-LABEL: define i1 @test_with_unfoldable_phi(
|
|
; CHECK-SAME: i1 [[COND:%.*]], i64 [[LEFT:%.*]], i64 [[RIGHT:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*]]:
|
|
; CHECK-NEXT: br i1 [[COND]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
|
|
; CHECK: [[COND_TRUE]]:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[RIGHT]], [[LEFT]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label %[[END:.*]], label %[[COND_FALSE]]
|
|
; CHECK: [[COND_FALSE]]:
|
|
; CHECK-NEXT: [[LEFT_OR_RIGHT:%.*]] = phi i64 [ [[LEFT]], %[[START]] ], [ [[RIGHT]], %[[COND_TRUE]] ]
|
|
; CHECK-NEXT: [[FALSE:%.*]] = icmp sgt i64 [[LEFT_OR_RIGHT]], [[LEFT]]
|
|
; CHECK-NEXT: br label %[[END]]
|
|
; CHECK: [[END]]:
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i1 [ false, %[[COND_TRUE]] ], [ [[FALSE]], %[[COND_FALSE]] ]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
br i1 %cond, label %cond.true, label %cond.false
|
|
|
|
cond.true:
|
|
%cmp = icmp slt i64 %right, %left ; slt instead of sgt here
|
|
br i1 %cmp, label %end, label %cond.false
|
|
|
|
cond.false:
|
|
%left_or_right = phi i64 [ %left, %start ], [ %right, %cond.true ]
|
|
%false = icmp sgt i64 %left_or_right, %left
|
|
br label %end
|
|
|
|
end:
|
|
%result = phi i1 [ false, %cond.true ], [ %false, %cond.false ]
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @test_which_optimizes_to_select(i1 %cond, i64 %left, i64 %right) {
|
|
; CHECK-LABEL: define i1 @test_which_optimizes_to_select(
|
|
; CHECK-SAME: i1 [[COND:%.*]], i64 [[LEFT:%.*]], i64 [[RIGHT:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: br i1 [[COND]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
|
|
; CHECK: [[COND_TRUE]]:
|
|
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i64 [[RIGHT]], [[LEFT]]
|
|
; CHECK-NEXT: br i1 [[CMP_NOT]], label %[[COND_FALSE]], label %[[END:.*]]
|
|
; CHECK: [[COND_FALSE]]:
|
|
; CHECK-NEXT: br label %[[END]]
|
|
; CHECK: [[END]]:
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i1 [ false, %[[COND_TRUE]] ], [ [[COND]], %[[COND_FALSE]] ]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
br i1 %cond, label %cond.true, label %cond.false
|
|
|
|
cond.true:
|
|
%cmp = icmp sle i64 %right, %left
|
|
br i1 %cmp, label %end, label %cond.false
|
|
|
|
cond.false:
|
|
%left_or_right = phi i64 [ %left, %start ], [ %right, %cond.true ]
|
|
%false = icmp sgt i64 %left_or_right, %left
|
|
br label %end
|
|
|
|
end:
|
|
%result = phi i1 [ false, %cond.true ], [ %false, %cond.false ]
|
|
ret i1 %result
|
|
}
|