llvm-6502/test/Transforms/InstCombine/dom-conditions.ll
Philip Reames 7c7b72a066 Infer known bits from dominating conditions
This patch adds limited support in ValueTracking for inferring known bits of a value from conditional expressions which must be true to reach the instruction we're trying to optimize. At this time, the feature is off by default. Once landed, I'm hoping for feedback from others on both profitability and compile time impact.

Forms of conditional value propagation have been tried in LLVM before and have failed due to compile time problems.  In an attempt to side step that, this patch only considers conditions where the edge leaving the branch dominates the context instruction. It does not attempt full dataflow.  Even with that restriction, it handles many interesting cases:
 * Early exits from functions
 * Early exits from loops (for context instructions in the loop and after the check)
 * Conditions which control entry into loops, including multi-version loops (such as those produced during vectorization, IRCE, loop unswitch, etc..)

Possible applications include optimizing using information provided by constructs such as: preconditions, assumptions, null checks, & range checks.

This patch implements two approaches to the problem that need further benchmarking.  Approach 1 is to directly walk the dominator tree looking for interesting conditions.  Approach 2 is to inspect other uses of the value being queried for interesting comparisons.  From initial benchmarking, it appears that Approach 2 is faster than Approach 1, but this needs to be further validated.  

Differential Revision: http://reviews.llvm.org/D7708



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231879 91177308-0d34-0410-b5e6-96231b3b80d8
2015-03-10 22:43:20 +00:00

153 lines
3.2 KiB
LLVM

; RUN: opt -instcombine -value-tracking-dom-conditions=1 -S < %s | FileCheck %s
target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
define i1 @test_cmp_ult(i64 %A) {
; CHECK-LABEL: @test_cmp_ult
entry:
%cmp = icmp ult i64 %A, 64
br i1 %cmp, label %taken, label %untaken
taken:
; CHECK-LABEL: taken:
; CHECK-NEXT: ret i1 false
%cmp2 = icmp ugt i64 %A, 64
ret i1 %cmp2
untaken:
ret i1 true
}
define i1 @test_cmp_ule(i64 %A) {
; CHECK-LABEL: @test_cmp_ule
entry:
%cmp = icmp ule i64 %A, 64
br i1 %cmp, label %taken, label %untaken
taken:
; CHECK-LABEL: taken:
; CHECK-NEXT: ret i1 false
%cmp2 = icmp ugt i64 %A, 128
ret i1 %cmp2
untaken:
ret i1 true
}
define i1 @test_cmp_sgt(i32 %A) {
; CHECK-LABEL: @test_cmp_sgt
entry:
%cmp = icmp sgt i32 %A, 10
br i1 %cmp, label %taken, label %untaken
taken:
; CHECK-LABEL: taken:
; CHECK-NEXT: ret i1 true
%cmp2 = icmp sgt i32 %A, -1
ret i1 %cmp2
untaken:
ret i1 true
}
define i64 @test_add_zero_bits(i64 %A) {
; CHECK-LABEL: @test_add_zero_bits
entry:
%cmp = icmp eq i64 %A, 2
br i1 %cmp, label %taken, label %untaken
taken:
; CHECK-LABEL: taken:
; CHECK-NEXT: ret i64 3
%add = add i64 %A, 1
ret i64 %add
untaken:
ret i64 %A
}
define i64 @test_add_nsw(i64 %A) {
; CHECK-LABEL: @test_add_nsw
entry:
%cmp = icmp ult i64 %A, 20
br i1 %cmp, label %taken, label %untaken
taken:
; CHECK-LABEL: taken:
; CHECK-NEXT: %add = add nuw nsw i64 %A, 1
; CHECK-NEXT: ret i64 %add
%add = add i64 %A, 1
ret i64 %add
untaken:
ret i64 %A
}
; After sinking the instructions into the if block, check that we
; can simplify some of them using dominating conditions.
define i32 @test_add_zero_bits_sink(i32 %x) nounwind ssp {
; CHECK-LABEL: @test_add_zero_bits_sink(
; CHECK-NOT: sdiv i32
entry:
%a = add nsw i32 %x, 16
%b = sdiv i32 %a, %x
%cmp = icmp ult i32 %x, 7
br i1 %cmp, label %bb1, label %bb2
bb1:
; CHECK-LABEL: bb1:
; CHECK-NEXT: or i32 %x, 16
; CHECK-NEXT: udiv i32
ret i32 %b
bb2:
ret i32 %x
}
; A condition in the same block gives no information
define i32 @test_neg1(i32 %x) nounwind ssp {
; CHECK-LABEL: @test_neg1
; CHECK: add
; CHECK: sdiv
; CHECK: icmp
; CHECK: select
entry:
%a = add nsw i32 %x, 16
%b = sdiv i32 %a, %x
%cmp = icmp ult i32 %x, 7
%ret = select i1 %cmp, i32 %a, i32 %b
ret i32 %ret
}
; A non-dominating edge gives no information
define i32 @test_neg2(i32 %x) {
; CHECK-LABEL: @test_neg2
entry:
%cmp = icmp ult i32 %x, 7
br i1 %cmp, label %bb1, label %merge
bb1:
br label %merge
merge:
; CHECK-LABEL: merge:
; CHECK: icmp
; CHECK: select
%cmp2 = icmp ult i32 %x, 7
%ret = select i1 %cmp2, i32 %x, i32 0
ret i32 %ret
}
; A unconditional branch expressed as a condition one gives no
; information (and shouldn't trip any asserts.)
define i32 @test_neg3(i32 %x) {
; CHECK-LABEL: @test_neg3
entry:
%cmp = icmp ult i32 %x, 7
br i1 %cmp, label %merge, label %merge
merge:
; CHECK-LABEL: merge:
; CHECK: icmp
; CHECK: select
%cmp2 = icmp ult i32 %x, 7
%ret = select i1 %cmp2, i32 %x, i32 0
ret i32 %ret
}
declare i32 @bar()