1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s 3 4 ; LSR should be able to eliminate both smax and umax expressions 5 ; in loop trip counts. 6 7 target datalayout = "e-p: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" 8 9 define void @fs(double* nocapture %p, i64 %n) nounwind { 10 ; CHECK-LABEL: fs: 11 ; CHECK: # %bb.0: # %entry 12 ; CHECK-NEXT: xorl %eax, %eax 13 ; CHECK-NEXT: .p2align 4, 0x90 14 ; CHECK-NEXT: .LBB0_1: # %bb 15 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 16 ; CHECK-NEXT: movq $0, (%rdi,%rax,8) 17 ; CHECK-NEXT: incq %rax 18 ; CHECK-NEXT: cmpq %rsi, %rax 19 ; CHECK-NEXT: jl .LBB0_1 20 ; CHECK-NEXT: # %bb.2: # %return 21 ; CHECK-NEXT: retq 22 entry: 23 %tmp = icmp slt i64 %n, 1 ; <i1> [#uses=1] 24 %smax = select i1 %tmp, i64 1, i64 %n ; <i64> [#uses=1] 25 br label %bb 26 27 bb: ; preds = %bb, %entry 28 %i.0 = phi i64 [ 0, %entry ], [ %0, %bb ] ; <i64> [#uses=2] 29 %scevgep = getelementptr double, double* %p, i64 %i.0 ; <double*> [#uses=1] 30 store double 0.000000e+00, double* %scevgep, align 8 31 %0 = add i64 %i.0, 1 ; <i64> [#uses=2] 32 %exitcond = icmp eq i64 %0, %smax ; <i1> [#uses=1] 33 br i1 %exitcond, label %return, label %bb 34 35 return: ; preds = %bb 36 ret void 37 } 38 39 define void @bs(double* nocapture %p, i64 %n) nounwind { 40 ; CHECK-LABEL: bs: 41 ; CHECK: # %bb.0: # %entry 42 ; CHECK-NEXT: xorl %eax, %eax 43 ; CHECK-NEXT: .p2align 4, 0x90 44 ; CHECK-NEXT: .LBB1_1: # %bb 45 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 46 ; CHECK-NEXT: movq $0, (%rdi,%rax,8) 47 ; CHECK-NEXT: incq %rax 48 ; CHECK-NEXT: cmpq %rsi, %rax 49 ; CHECK-NEXT: jl .LBB1_1 50 ; CHECK-NEXT: # %bb.2: # %return 51 ; CHECK-NEXT: retq 52 entry: 53 %tmp = icmp sge i64 %n, 1 ; <i1> [#uses=1] 54 %smax = select i1 %tmp, i64 %n, i64 1 ; <i64> [#uses=1] 55 br label %bb 56 57 bb: ; preds = %bb, %entry 58 %i.0 = phi i64 [ 0, %entry ], [ %0, %bb ] ; <i64> [#uses=2] 59 %scevgep = getelementptr double, double* %p, i64 %i.0 ; <double*> [#uses=1] 60 store double 0.000000e+00, double* %scevgep, align 8 61 %0 = add i64 %i.0, 1 ; <i64> [#uses=2] 62 %exitcond = icmp eq i64 %0, %smax ; <i1> [#uses=1] 63 br i1 %exitcond, label %return, label %bb 64 65 return: ; preds = %bb 66 ret void 67 } 68 69 define void @fu(double* nocapture %p, i64 %n) nounwind { 70 ; CHECK-LABEL: fu: 71 ; CHECK: # %bb.0: # %entry 72 ; CHECK-NEXT: xorl %eax, %eax 73 ; CHECK-NEXT: .p2align 4, 0x90 74 ; CHECK-NEXT: .LBB2_1: # %bb 75 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 76 ; CHECK-NEXT: movq $0, (%rdi,%rax,8) 77 ; CHECK-NEXT: incq %rax 78 ; CHECK-NEXT: cmpq %rsi, %rax 79 ; CHECK-NEXT: jb .LBB2_1 80 ; CHECK-NEXT: # %bb.2: # %return 81 ; CHECK-NEXT: retq 82 entry: 83 %tmp = icmp eq i64 %n, 0 ; <i1> [#uses=1] 84 %umax = select i1 %tmp, i64 1, i64 %n ; <i64> [#uses=1] 85 br label %bb 86 87 bb: ; preds = %bb, %entry 88 %i.0 = phi i64 [ 0, %entry ], [ %0, %bb ] ; <i64> [#uses=2] 89 %scevgep = getelementptr double, double* %p, i64 %i.0 ; <double*> [#uses=1] 90 store double 0.000000e+00, double* %scevgep, align 8 91 %0 = add i64 %i.0, 1 ; <i64> [#uses=2] 92 %exitcond = icmp eq i64 %0, %umax ; <i1> [#uses=1] 93 br i1 %exitcond, label %return, label %bb 94 95 return: ; preds = %bb 96 ret void 97 } 98 99 define void @bu(double* nocapture %p, i64 %n) nounwind { 100 ; CHECK-LABEL: bu: 101 ; CHECK: # %bb.0: # %entry 102 ; CHECK-NEXT: xorl %eax, %eax 103 ; CHECK-NEXT: .p2align 4, 0x90 104 ; CHECK-NEXT: .LBB3_1: # %bb 105 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 106 ; CHECK-NEXT: movq $0, (%rdi,%rax,8) 107 ; CHECK-NEXT: incq %rax 108 ; CHECK-NEXT: cmpq %rsi, %rax 109 ; CHECK-NEXT: jb .LBB3_1 110 ; CHECK-NEXT: # %bb.2: # %return 111 ; CHECK-NEXT: retq 112 entry: 113 %tmp = icmp ne i64 %n, 0 ; <i1> [#uses=1] 114 %umax = select i1 %tmp, i64 %n, i64 1 ; <i64> [#uses=1] 115 br label %bb 116 117 bb: ; preds = %bb, %entry 118 %i.0 = phi i64 [ 0, %entry ], [ %0, %bb ] ; <i64> [#uses=2] 119 %scevgep = getelementptr double, double* %p, i64 %i.0 ; <double*> [#uses=1] 120 store double 0.000000e+00, double* %scevgep, align 8 121 %0 = add i64 %i.0, 1 ; <i64> [#uses=2] 122 %exitcond = icmp eq i64 %0, %umax ; <i1> [#uses=1] 123 br i1 %exitcond, label %return, label %bb 124 125 return: ; preds = %bb 126 ret void 127 } 128