1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define i8 @single(i32 %A) { 5; CHECK-LABEL: @single( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[CONV71:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 -128) 8; CHECK-NEXT: [[CONV7:%.*]] = trunc i32 [[CONV71]] to i8 9; CHECK-NEXT: ret i8 [[CONV7]] 10; 11entry: 12 %l1 = icmp slt i32 %A, -128 13 %l2 = select i1 %l1, i32 128, i32 %A 14 %conv7 = trunc i32 %l2 to i8 15 ret i8 %conv7 16} 17 18define i8 @double(i32 %A) { 19; CHECK-LABEL: @double( 20; CHECK-NEXT: entry: 21; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 -128) 22; CHECK-NEXT: [[CONV71:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP0]], i32 127) 23; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i32 [[CONV71]] to i8 24; CHECK-NEXT: ret i8 [[CONV7]] 25; 26entry: 27 %l1 = icmp slt i32 %A, -128 28 %l2 = select i1 %l1, i32 128, i32 %A 29 %.inv = icmp sgt i32 %A, 127 30 %spec.select.i = select i1 %.inv, i32 127, i32 %l2 31 %conv7 = trunc i32 %spec.select.i to i8 32 ret i8 %conv7 33} 34 35define i8 @thisdoesnotloop(i32 %A, i32 %B) { 36; CHECK-LABEL: @thisdoesnotloop( 37; CHECK-NEXT: entry: 38; CHECK-NEXT: [[L1:%.*]] = icmp slt i32 [[A:%.*]], -128 39; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[B:%.*]] to i8 40; CHECK-NEXT: [[CONV7:%.*]] = select i1 [[L1]], i8 -128, i8 [[TMP0]] 41; CHECK-NEXT: ret i8 [[CONV7]] 42; 43entry: 44 %l1 = icmp slt i32 %A, -128 45 %l2 = select i1 %l1, i32 128, i32 %B 46 %conv7 = trunc i32 %l2 to i8 47 ret i8 %conv7 48} 49 50define i8 @original(i32 %A, i32 %B) { 51; CHECK-LABEL: @original( 52; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 -128) 53; CHECK-NEXT: [[SPEC_SELECT_I:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 127) 54; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i32 [[SPEC_SELECT_I]] to i8 55; CHECK-NEXT: ret i8 [[CONV7]] 56; 57 %cmp4.i = icmp slt i32 127, %A 58 %cmp6.i = icmp sle i32 -128, %A 59 %retval.0.i = select i1 %cmp4.i, i32 127, i32 -128 60 %not.cmp4.i = xor i1 %cmp4.i, true 61 %cleanup.dest.slot.0.i = and i1 %cmp6.i, %not.cmp4.i 62 %spec.select.i = select i1 %cleanup.dest.slot.0.i, i32 %A, i32 %retval.0.i 63 %conv7 = trunc i32 %spec.select.i to i8 64 ret i8 %conv7 65} 66 67define i8 @original_logical(i32 %A, i32 %B) { 68; CHECK-LABEL: @original_logical( 69; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 -128) 70; CHECK-NEXT: [[SPEC_SELECT_I:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 127) 71; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i32 [[SPEC_SELECT_I]] to i8 72; CHECK-NEXT: ret i8 [[CONV7]] 73; 74 %cmp4.i = icmp slt i32 127, %A 75 %cmp6.i = icmp sle i32 -128, %A 76 %retval.0.i = select i1 %cmp4.i, i32 127, i32 -128 77 %not.cmp4.i = xor i1 %cmp4.i, true 78 %cleanup.dest.slot.0.i = select i1 %cmp6.i, i1 %not.cmp4.i, i1 false 79 %spec.select.i = select i1 %cleanup.dest.slot.0.i, i32 %A, i32 %retval.0.i 80 %conv7 = trunc i32 %spec.select.i to i8 81 ret i8 %conv7 82} 83 84; This would infinite loop because we have potentially opposing 85; constant transforms on degenerate (unsimplified) cmps. 86 87define i32 @PR49205(i32 %t0, i1 %b) { 88; CHECK-LABEL: @PR49205( 89; CHECK-NEXT: entry: 90; CHECK-NEXT: br label [[FOR_COND:%.*]] 91; CHECK: for.cond: 92; CHECK-NEXT: br i1 [[B:%.*]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] 93; CHECK: for.body: 94; CHECK-NEXT: br label [[FOR_COND]] 95; CHECK: for.end: 96; CHECK-NEXT: ret i32 1 97; 98entry: 99 br label %for.cond 100 101for.cond: 102 %s = phi i32 [ 7, %entry ], [ %add, %for.body ] 103 br i1 %b, label %for.body, label %for.end 104 105for.body: 106 %div = add i32 %t0, undef 107 %add = add nsw i32 %div, 1 108 br label %for.cond 109 110for.end: 111 %cmp6 = icmp ne i32 %s, 4 112 %conv = zext i1 %cmp6 to i32 113 %and7 = and i32 %s, %conv 114 %sub = sub i32 %s, %and7 115 %cmp9 = icmp ne i32 %sub, 4 116 %conv10 = zext i1 %cmp9 to i32 117 %sub11 = sub i32 %conv10, %sub 118 %and = and i32 %sub11, 1 119 ret i32 %and 120} 121