1*9880d681SAndroid Build Coastguard Worker; Test 32-bit ordered comparisons that are really between a memory halfword 2*9880d681SAndroid Build Coastguard Worker; and a constant. 3*9880d681SAndroid Build Coastguard Worker; 4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker; Check unsigned comparison near the low end of the CLHHSI range, using zero 7*9880d681SAndroid Build Coastguard Worker; extension. 8*9880d681SAndroid Build Coastguard Workerdefine double @f1(double %a, double %b, i16 *%ptr) { 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 10*9880d681SAndroid Build Coastguard Worker; CHECK: clhhsi 0(%r2), 1 11*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 12*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 13*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 14*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %val to i32 15*9880d681SAndroid Build Coastguard Worker %cond = icmp ugt i32 %ext, 1 16*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 17*9880d681SAndroid Build Coastguard Worker ret double %res 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; Check unsigned comparison near the low end of the CLHHSI range, using sign 21*9880d681SAndroid Build Coastguard Worker; extension. 22*9880d681SAndroid Build Coastguard Workerdefine double @f2(double %a, double %b, i16 *%ptr) { 23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 24*9880d681SAndroid Build Coastguard Worker; CHECK: clhhsi 0(%r2), 1 25*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 26*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 27*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 28*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %val to i32 29*9880d681SAndroid Build Coastguard Worker %cond = icmp ugt i32 %ext, 1 30*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 31*9880d681SAndroid Build Coastguard Worker ret double %res 32*9880d681SAndroid Build Coastguard Worker} 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker; Check unsigned comparison near the high end of the CLHHSI range, using zero 35*9880d681SAndroid Build Coastguard Worker; extension. 36*9880d681SAndroid Build Coastguard Workerdefine double @f3(double %a, double %b, i16 *%ptr) { 37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 38*9880d681SAndroid Build Coastguard Worker; CHECK: clhhsi 0(%r2), 65534 39*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 40*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 41*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 42*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %val to i32 43*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %ext, 65534 44*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 45*9880d681SAndroid Build Coastguard Worker ret double %res 46*9880d681SAndroid Build Coastguard Worker} 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker; Check unsigned comparison near the high end of the CLHHSI range, using sign 49*9880d681SAndroid Build Coastguard Worker; extension. 50*9880d681SAndroid Build Coastguard Workerdefine double @f4(double %a, double %b, i16 *%ptr) { 51*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 52*9880d681SAndroid Build Coastguard Worker; CHECK: clhhsi 0(%r2), 65534 53*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 54*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 55*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 56*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %val to i32 57*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %ext, -2 58*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 59*9880d681SAndroid Build Coastguard Worker ret double %res 60*9880d681SAndroid Build Coastguard Worker} 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker; Check unsigned comparison above the high end of the CLHHSI range, using zero 63*9880d681SAndroid Build Coastguard Worker; extension. The condition is always true. 64*9880d681SAndroid Build Coastguard Workerdefine double @f5(double %a, double %b, i16 *%ptr) { 65*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 66*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clhhsi 67*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 68*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 69*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %val to i32 70*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %ext, 65536 71*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 72*9880d681SAndroid Build Coastguard Worker ret double %res 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker; When using unsigned comparison with sign extension, equality with values 76*9880d681SAndroid Build Coastguard Worker; in the range [32768, MAX-32769] is impossible, and ordered comparisons with 77*9880d681SAndroid Build Coastguard Worker; those values are effectively sign tests. Since such comparisons are 78*9880d681SAndroid Build Coastguard Worker; unlikely to occur in practice, we don't bother optimizing the second case, 79*9880d681SAndroid Build Coastguard Worker; and simply ignore CLHHSI for this range. First check the low end of the 80*9880d681SAndroid Build Coastguard Worker; range. 81*9880d681SAndroid Build Coastguard Workerdefine double @f6(double %a, double %b, i16 *%ptr) { 82*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 83*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clhhsi 84*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 85*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 86*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %val to i32 87*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %ext, 32768 88*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 89*9880d681SAndroid Build Coastguard Worker ret double %res 90*9880d681SAndroid Build Coastguard Worker} 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker; ...and then the high end. 93*9880d681SAndroid Build Coastguard Workerdefine double @f7(double %a, double %b, i16 *%ptr) { 94*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 95*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clhhsi 96*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 97*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 98*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %val to i32 99*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %ext, -32769 100*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 101*9880d681SAndroid Build Coastguard Worker ret double %res 102*9880d681SAndroid Build Coastguard Worker} 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Worker; Check signed comparison near the low end of the CLHHSI range, using zero 105*9880d681SAndroid Build Coastguard Worker; extension. This is equivalent to unsigned comparison. 106*9880d681SAndroid Build Coastguard Workerdefine double @f8(double %a, double %b, i16 *%ptr) { 107*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 108*9880d681SAndroid Build Coastguard Worker; CHECK: clhhsi 0(%r2), 1 109*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 110*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 111*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 112*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %val to i32 113*9880d681SAndroid Build Coastguard Worker %cond = icmp sgt i32 %ext, 1 114*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 115*9880d681SAndroid Build Coastguard Worker ret double %res 116*9880d681SAndroid Build Coastguard Worker} 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker; Check signed comparison near the low end of the CLHHSI range, using sign 119*9880d681SAndroid Build Coastguard Worker; extension. This should use CHHSI instead. 120*9880d681SAndroid Build Coastguard Workerdefine double @f9(double %a, double %b, i16 *%ptr) { 121*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9: 122*9880d681SAndroid Build Coastguard Worker; CHECK: chhsi 0(%r2), 1 123*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 124*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 125*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 126*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %val to i32 127*9880d681SAndroid Build Coastguard Worker %cond = icmp sgt i32 %ext, 1 128*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 129*9880d681SAndroid Build Coastguard Worker ret double %res 130*9880d681SAndroid Build Coastguard Worker} 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker; Check signed comparison near the high end of the CLHHSI range, using zero 133*9880d681SAndroid Build Coastguard Worker; extension. This is equivalent to unsigned comparison. 134*9880d681SAndroid Build Coastguard Workerdefine double @f10(double %a, double %b, i16 *%ptr) { 135*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10: 136*9880d681SAndroid Build Coastguard Worker; CHECK: clhhsi 0(%r2), 65534 137*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 138*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 139*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 140*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %val to i32 141*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %ext, 65534 142*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 143*9880d681SAndroid Build Coastguard Worker ret double %res 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker; Check signed comparison near the high end of the CLHHSI range, using sign 147*9880d681SAndroid Build Coastguard Worker; extension. This should use CHHSI instead. 148*9880d681SAndroid Build Coastguard Workerdefine double @f11(double %a, double %b, i16 *%ptr) { 149*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11: 150*9880d681SAndroid Build Coastguard Worker; CHECK: chhsi 0(%r2), -2 151*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 152*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 153*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 154*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %val to i32 155*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %ext, -2 156*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 157*9880d681SAndroid Build Coastguard Worker ret double %res 158*9880d681SAndroid Build Coastguard Worker} 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Worker; Check signed comparison above the high end of the CLHHSI range, using zero 161*9880d681SAndroid Build Coastguard Worker; extension. The condition is always true. 162*9880d681SAndroid Build Coastguard Workerdefine double @f12(double %a, double %b, i16 *%ptr) { 163*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12: 164*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: cli 165*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 166*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 167*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %val to i32 168*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %ext, 65536 169*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 170*9880d681SAndroid Build Coastguard Worker ret double %res 171*9880d681SAndroid Build Coastguard Worker} 172*9880d681SAndroid Build Coastguard Worker 173*9880d681SAndroid Build Coastguard Worker; Check signed comparison near the high end of the CHHSI range, using sign 174*9880d681SAndroid Build Coastguard Worker; extension. 175*9880d681SAndroid Build Coastguard Workerdefine double @f13(double %a, double %b, i16 *%ptr) { 176*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13: 177*9880d681SAndroid Build Coastguard Worker; CHECK: chhsi 0(%r2), 32766 178*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 179*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 180*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 181*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %val to i32 182*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %ext, 32766 183*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 184*9880d681SAndroid Build Coastguard Worker ret double %res 185*9880d681SAndroid Build Coastguard Worker} 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Worker; Check signed comparison above the high end of the CHHSI range, using sign 188*9880d681SAndroid Build Coastguard Worker; extension. This condition is always true. 189*9880d681SAndroid Build Coastguard Workerdefine double @f14(double %a, double %b, i16 *%ptr) { 190*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f14: 191*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: chhsi 192*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 193*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 194*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %val to i32 195*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %ext, 32768 196*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 197*9880d681SAndroid Build Coastguard Worker ret double %res 198*9880d681SAndroid Build Coastguard Worker} 199*9880d681SAndroid Build Coastguard Worker 200*9880d681SAndroid Build Coastguard Worker; Check signed comparison near the low end of the CHHSI range, using sign 201*9880d681SAndroid Build Coastguard Worker; extension. 202*9880d681SAndroid Build Coastguard Workerdefine double @f15(double %a, double %b, i16 *%ptr) { 203*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f15: 204*9880d681SAndroid Build Coastguard Worker; CHECK: chhsi 0(%r2), -32767 205*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 206*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 207*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 208*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %val to i32 209*9880d681SAndroid Build Coastguard Worker %cond = icmp sgt i32 %ext, -32767 210*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 211*9880d681SAndroid Build Coastguard Worker ret double %res 212*9880d681SAndroid Build Coastguard Worker} 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Worker; Check signed comparison below the low end of the CHHSI range, using sign 215*9880d681SAndroid Build Coastguard Worker; extension. This condition is always true. 216*9880d681SAndroid Build Coastguard Workerdefine double @f16(double %a, double %b, i16 *%ptr) { 217*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f16: 218*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: chhsi 219*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 220*9880d681SAndroid Build Coastguard Worker %val = load i16 , i16 *%ptr 221*9880d681SAndroid Build Coastguard Worker %ext = sext i16 %val to i32 222*9880d681SAndroid Build Coastguard Worker %cond = icmp sgt i32 %ext, -32769 223*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 224*9880d681SAndroid Build Coastguard Worker ret double %res 225*9880d681SAndroid Build Coastguard Worker} 226