Index: llvm/test/Transforms/InstCombine/load-cmp-index.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/InstCombine/load-cmp-index.ll @@ -0,0 +1,119 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 +; RUN: opt -passes=instcombine -S < %s | FileCheck %s + +@CG = constant [4 x i32] [i32 1, i32 2, i32 3, i32 4] + +define i1 @cmp_load_constant_array0(i64 %x){ +; CHECK-LABEL: define i1 @cmp_load_constant_array0 +; CHECK-SAME: (i64 [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[COND:%.*]] = icmp ult i64 [[X]], 2 +; CHECK-NEXT: br i1 [[COND]], label [[CASE1:%.*]], label [[CASE2:%.*]] +; CHECK: case2: +; CHECK-NEXT: ret i1 false +; CHECK: case1: +; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr inbounds i32, ptr @CG, i64 [[X]] +; CHECK-NEXT: [[ISOK:%.*]] = load i32, ptr [[ISOK_PTR]], align 4 +; CHECK-NEXT: [[COND_INFERRED:%.*]] = icmp ult i32 [[ISOK]], 3 +; CHECK-NEXT: ret i1 [[COND_INFERRED]] +; +entry: + %cond = icmp ult i64 %x, 2 + br i1 %cond, label %case1, label %case2 + +case2: + ret i1 0 + +case1: + %isOK_ptr = getelementptr inbounds i32, ptr @CG, i64 %x + %isOK = load i32, ptr %isOK_ptr + %cond_inferred = icmp ult i32 %isOK, 3 + ret i1 %cond_inferred +} + +define i1 @cmp_load_constant_array1(i64 %x){ +; CHECK-LABEL: define i1 @cmp_load_constant_array1 +; CHECK-SAME: (i64 [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[COND:%.*]] = icmp ult i64 [[X]], 2 +; CHECK-NEXT: br i1 [[COND]], label [[CASE1:%.*]], label [[CASE2:%.*]] +; CHECK: case2: +; CHECK-NEXT: ret i1 false +; CHECK: case1: +; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr inbounds i32, ptr @CG, i64 [[X]] +; CHECK-NEXT: [[ISOK:%.*]] = load i32, ptr [[ISOK_PTR]], align 4 +; CHECK-NEXT: [[COND_INFERRED:%.*]] = icmp ugt i32 [[ISOK]], 10 +; CHECK-NEXT: ret i1 [[COND_INFERRED]] +; +entry: + %cond = icmp ult i64 %x, 2 + br i1 %cond, label %case1, label %case2 + +case2: + ret i1 0 + +case1: + %isOK_ptr = getelementptr inbounds i32, ptr @CG, i64 %x + %isOK = load i32, ptr %isOK_ptr + %cond_inferred = icmp ugt i32 %isOK, 10 + ret i1 %cond_inferred +} + +define i1 @cmp_load_constant_array_fail0(i64 %x) { +; CHECK-LABEL: define i1 @cmp_load_constant_array_fail0 +; CHECK-SAME: (i64 [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[COND:%.*]] = icmp ult i64 [[X]], 6 +; CHECK-NEXT: br i1 [[COND]], label [[CASE1:%.*]], label [[CASE2:%.*]] +; CHECK: case2: +; CHECK-NEXT: ret i1 false +; CHECK: case1: +; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr inbounds i32, ptr @CG, i64 [[X]] +; CHECK-NEXT: [[ISOK:%.*]] = load i32, ptr [[ISOK_PTR]], align 4 +; CHECK-NEXT: [[COND_INFERRED:%.*]] = icmp ult i32 [[ISOK]], 5 +; CHECK-NEXT: ret i1 [[COND_INFERRED]] +; +entry: + %cond = icmp ult i64 %x, 6 + br i1 %cond, label %case1, label %case2 + +case2: + ret i1 0 + +case1: + %isOK_ptr = getelementptr inbounds i32, ptr @CG, i64 %x + %isOK = load i32, ptr %isOK_ptr + %cond_inferred = icmp ult i32 %isOK, 5 + ret i1 %cond_inferred +} + +define i1 @cmp_load_constant_array_fail1(i64 %x){ +; CHECK-LABEL: define i1 @cmp_load_constant_array_fail1 +; CHECK-SAME: (i64 [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[X]], -1 +; CHECK-NEXT: [[COND3:%.*]] = icmp ult i64 [[TMP0]], 2 +; CHECK-NEXT: br i1 [[COND3]], label [[CASE1:%.*]], label [[CASE2:%.*]] +; CHECK: case2: +; CHECK-NEXT: ret i1 false +; CHECK: case1: +; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr inbounds i32, ptr @CG, i64 [[X]] +; CHECK-NEXT: [[ISOK:%.*]] = load i32, ptr [[ISOK_PTR]], align 4 +; CHECK-NEXT: [[COND_INFERRED:%.*]] = icmp ugt i32 [[ISOK]], 1 +; CHECK-NEXT: ret i1 [[COND_INFERRED]] +; +entry: + %cond1 = icmp ult i64 %x, 3 + %cond2 = icmp ugt i64 %x, 0 + %cond3 = and i1 %cond1,%cond2 + br i1 %cond3, label %case1, label %case2 + +case2: + ret i1 0 + +case1: + %isOK_ptr = getelementptr inbounds i32, ptr @CG, i64 %x + %isOK = load i32, ptr %isOK_ptr + %cond_inferred = icmp ugt i32 %isOK, 1 + ret i1 %cond_inferred +}