Originally reported in Rust: https://github.com/rust-lang/rust/issues/58602
llvm define i64 @test_icmp_sub_elide(i64 %offset) { start: %0 = icmp ult i64 %offset, 8 br i1 %0, label %body, label %end body: %1 = sub i64 10, %offset %2 = icmp ult i64 %1, 3 br i1 %2, label %dead_branch, label %end dead_branch: ret i64 %1 end: ret i64 0 }
In the above snippet, we already check that offset < 8 in the first block but can't figure out that 10-offset < 3 is redundant. This changes fixes it in 2 parts:
Teach CorrelatedValuePropagation to also handle sub instructions in addition to add. Relatively simple since makeGuaranteedNoWrapRegion already understood sub instructions. Only subtle change is which range is passed as "Other" to that function, since sub isn't commutative.Moved to separate revision: D60036- Teach InstCombine the transformation (icmp P (sub nuw|nsw C2, Y), C) -> (icmp swap(P) Y, C2-C)