1; RUN: opt -S -instcombine < %s | FileCheck %s 2 3; CHECK-LABEL: @t1 4; CHECK-NEXT: icmp 5; CHECK-NEXT: select 6; CHECK-NEXT: sext 7define i64 @t1(i32 %a) { 8 ; This is the canonical form for a type-changing min/max. 9 %1 = icmp slt i32 %a, 5 10 %2 = select i1 %1, i32 %a, i32 5 11 %3 = sext i32 %2 to i64 12 ret i64 %3 13} 14 15; CHECK-LABEL: @t2 16; CHECK-NEXT: icmp 17; CHECK-NEXT: select 18; CHECK-NEXT: sext 19define i64 @t2(i32 %a) { 20 ; Check this is converted into canonical form, as above. 21 %1 = icmp slt i32 %a, 5 22 %2 = sext i32 %a to i64 23 %3 = select i1 %1, i64 %2, i64 5 24 ret i64 %3 25} 26 27; CHECK-LABEL: @t3 28; CHECK-NEXT: icmp 29; CHECK-NEXT: select 30; CHECK-NEXT: zext 31define i64 @t3(i32 %a) { 32 ; Same as @t2, with flipped operands and zext instead of sext. 33 %1 = icmp ult i32 %a, 5 34 %2 = zext i32 %a to i64 35 %3 = select i1 %1, i64 5, i64 %2 36 ret i64 %3 37} 38 39; CHECK-LABEL: @t4 40; CHECK-NEXT: icmp 41; CHECK-NEXT: select 42; CHECK-NEXT: trunc 43define i32 @t4(i64 %a) { 44 ; Same again, with trunc. 45 %1 = icmp slt i64 %a, 5 46 %2 = trunc i64 %a to i32 47 %3 = select i1 %1, i32 %2, i32 5 48 ret i32 %3 49} 50 51; CHECK-LABEL: @t5 52; CHECK-NEXT: icmp 53; CHECK-NEXT: zext 54; CHECK-NEXT: select 55define i64 @t5(i32 %a) { 56 ; Same as @t3, but with mismatched signedness between icmp and zext. 57 ; InstCombine should leave this alone. 58 %1 = icmp slt i32 %a, 5 59 %2 = zext i32 %a to i64 60 %3 = select i1 %1, i64 5, i64 %2 61 ret i64 %3 62} 63 64; CHECK-LABEL: @t6 65; CHECK-NEXT: icmp 66; CHECK-NEXT: select 67; CHECK-NEXT: sitofp 68define float @t6(i32 %a) { 69 %1 = icmp slt i32 %a, 0 70 %2 = select i1 %1, i32 %a, i32 0 71 %3 = sitofp i32 %2 to float 72 ret float %3 73} 74 75; CHECK-LABEL: @t7 76; CHECK-NEXT: icmp 77; CHECK-NEXT: select 78; CHECK-NEXT: trunc 79define i16 @t7(i32 %a) { 80 %1 = icmp slt i32 %a, -32768 81 %2 = trunc i32 %a to i16 82 %3 = select i1 %1, i16 %2, i16 -32768 83 ret i16 %3 84} 85 86; Just check for no infinite loop. InstSimplify liked to 87; "simplify" -32767 by removing all the sign bits, 88; which led to a canonicalization fight between different 89; parts of instcombine. 90define i32 @t8(i64 %a, i32 %b) { 91 %1 = icmp slt i64 %a, -32767 92 %2 = select i1 %1, i64 %a, i64 -32767 93 %3 = trunc i64 %2 to i32 94 %4 = icmp slt i32 %b, 42 95 %5 = select i1 %4, i32 42, i32 %3 96 %6 = icmp ne i32 %5, %b 97 %7 = zext i1 %6 to i32 98 ret i32 %7 99} 100 101; Ensure this doesn't get converted to a min/max. 102; CHECK-LABEL: @t9 103; CHECK-NEXT: icmp 104; CHECK-NEXT: sext 105; CHECK-NEXT: 4294967295 106; CHECK-NEXT: ret 107define i64 @t9(i32 %a) { 108 %1 = icmp sgt i32 %a, -1 109 %2 = sext i32 %a to i64 110 %3 = select i1 %1, i64 %2, i64 4294967295 111 ret i64 %3 112} 113