Files
clang-p2996/llvm/test/Transforms/CorrelatedValuePropagation/cond-using-block-value.ll
Nikita Popov 3127b659fa [CVP] Infer range return attribute (#99620)
We already infer this in IPSCCP (which runs very early, so cannot
benefit from inlining and simplifications) and SCCP (which runs without
PredicateInfo, so does not use assumes). Do it in CVP as well, so it can
handle cases that IPSCCP/SCCP can't.

Fixes https://github.com/llvm/llvm-project/issues/98946 (everything
apart from f2, where the assume is dropped by the frontend).
2024-09-20 14:29:19 +02:00

97 lines
2.7 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
; RUN: opt -S -passes=correlated-propagation < %s | FileCheck %s
declare void @use(i1)
define void @test_icmp_from_implied_cond(i32 %a, i32 %b) {
; CHECK-LABEL: define void @test_icmp_from_implied_cond(
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
; CHECK-NEXT: [[A_CMP:%.*]] = icmp ugt i32 [[A]], 32
; CHECK-NEXT: br i1 [[A_CMP]], label [[END:%.*]], label [[L1:%.*]]
; CHECK: l1:
; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[B]], [[A]]
; CHECK-NEXT: br i1 [[COND]], label [[L2:%.*]], label [[END]]
; CHECK: l2:
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[B_CMP2:%.*]] = icmp ult i32 [[B]], 31
; CHECK-NEXT: call void @use(i1 [[B_CMP2]])
; CHECK-NEXT: ret void
; CHECK: end:
; CHECK-NEXT: ret void
;
%a.cmp = icmp ugt i32 %a, 32
br i1 %a.cmp, label %end, label %l1
l1:
%cond = icmp ult i32 %b, %a
br i1 %cond, label %l2, label %end
l2:
%b.cmp1 = icmp ult i32 %b, 32
call void @use(i1 %b.cmp1)
%b.cmp2 = icmp ult i32 %b, 31
call void @use(i1 %b.cmp2)
ret void
end:
ret void
}
define i64 @test_sext_from_implied_cond(i32 %a, i32 %b) {
; CHECK-LABEL: define range(i64 0, 2147483647) i64 @test_sext_from_implied_cond(
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
; CHECK-NEXT: [[A_CMP:%.*]] = icmp slt i32 [[A]], 0
; CHECK-NEXT: br i1 [[A_CMP]], label [[END:%.*]], label [[L1:%.*]]
; CHECK: l1:
; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[B]], [[A]]
; CHECK-NEXT: br i1 [[COND]], label [[L2:%.*]], label [[END]]
; CHECK: l2:
; CHECK-NEXT: [[SEXT:%.*]] = zext nneg i32 [[B]] to i64
; CHECK-NEXT: ret i64 [[SEXT]]
; CHECK: end:
; CHECK-NEXT: ret i64 0
;
%a.cmp = icmp slt i32 %a, 0
br i1 %a.cmp, label %end, label %l1
l1:
%cond = icmp ult i32 %b, %a
br i1 %cond, label %l2, label %end
l2:
%sext = sext i32 %b to i64
ret i64 %sext
end:
ret i64 0
}
define void @test_icmp_from_implied_range(i16 %x, i32 %b) {
; CHECK-LABEL: define void @test_icmp_from_implied_range(
; CHECK-SAME: i16 [[X:%.*]], i32 [[B:%.*]]) {
; CHECK-NEXT: [[A:%.*]] = zext i16 [[X]] to i32
; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[B]], [[A]]
; CHECK-NEXT: br i1 [[COND]], label [[L1:%.*]], label [[END:%.*]]
; CHECK: l1:
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[B_CMP2:%.*]] = icmp ult i32 [[B]], 65534
; CHECK-NEXT: call void @use(i1 [[B_CMP2]])
; CHECK-NEXT: ret void
; CHECK: end:
; CHECK-NEXT: ret void
;
%a = zext i16 %x to i32
%cond = icmp ult i32 %b, %a
br i1 %cond, label %l1, label %end
l1:
%b.cmp1 = icmp ult i32 %b, 65535
call void @use(i1 %b.cmp1)
%b.cmp2 = icmp ult i32 %b, 65534
call void @use(i1 %b.cmp2)
ret void
end:
ret void
}