1*9880d681SAndroid Build Coastguard Worker; Test 32-bit unsigned comparisons between memory and a constant. 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker; Check ordered comparisons with a constant near the low end of the unsigned 6*9880d681SAndroid Build Coastguard Worker; 16-bit range. 7*9880d681SAndroid Build Coastguard Workerdefine double @f1(double %a, double %b, i32 *%ptr) { 8*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 9*9880d681SAndroid Build Coastguard Worker; CHECK: clfhsi 0(%r2), 1 10*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 11*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 12*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 13*9880d681SAndroid Build Coastguard Worker %val = load i32 , i32 *%ptr 14*9880d681SAndroid Build Coastguard Worker %cond = icmp ugt i32 %val, 1 15*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 16*9880d681SAndroid Build Coastguard Worker ret double %res 17*9880d681SAndroid Build Coastguard Worker} 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker; Check ordered comparisons with the high end of the unsigned 16-bit range. 20*9880d681SAndroid Build Coastguard Workerdefine double @f2(double %a, double %b, i32 *%ptr) { 21*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 22*9880d681SAndroid Build Coastguard Worker; CHECK: clfhsi 0(%r2), 65535 23*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 24*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 25*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 26*9880d681SAndroid Build Coastguard Worker %val = load i32 , i32 *%ptr 27*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %val, 65535 28*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 29*9880d681SAndroid Build Coastguard Worker ret double %res 30*9880d681SAndroid Build Coastguard Worker} 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker; Check the next value up, which can't use CLFHSI. 33*9880d681SAndroid Build Coastguard Workerdefine double @f3(double %a, double %b, i32 *%ptr) { 34*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 35*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clfhsi 36*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 37*9880d681SAndroid Build Coastguard Worker %val = load i32 , i32 *%ptr 38*9880d681SAndroid Build Coastguard Worker %cond = icmp ult i32 %val, 65536 39*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 40*9880d681SAndroid Build Coastguard Worker ret double %res 41*9880d681SAndroid Build Coastguard Worker} 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker; Check equality comparisons with 32768, the lowest value for which 44*9880d681SAndroid Build Coastguard Worker; we prefer CLFHSI to CHSI. 45*9880d681SAndroid Build Coastguard Workerdefine double @f4(double %a, double %b, i32 *%ptr) { 46*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 47*9880d681SAndroid Build Coastguard Worker; CHECK: clfhsi 0(%r2), 32768 48*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ber %r14 49*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 50*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 51*9880d681SAndroid Build Coastguard Worker %val = load i32 , i32 *%ptr 52*9880d681SAndroid Build Coastguard Worker %cond = icmp eq i32 %val, 32768 53*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 54*9880d681SAndroid Build Coastguard Worker ret double %res 55*9880d681SAndroid Build Coastguard Worker} 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker; Check equality comparisons with the high end of the unsigned 16-bit range. 58*9880d681SAndroid Build Coastguard Workerdefine double @f5(double %a, double %b, i32 *%ptr) { 59*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 60*9880d681SAndroid Build Coastguard Worker; CHECK: clfhsi 0(%r2), 65535 61*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ber %r14 62*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 63*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 64*9880d681SAndroid Build Coastguard Worker %val = load i32 , i32 *%ptr 65*9880d681SAndroid Build Coastguard Worker %cond = icmp eq i32 %val, 65535 66*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 67*9880d681SAndroid Build Coastguard Worker ret double %res 68*9880d681SAndroid Build Coastguard Worker} 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker; Check the next value up, which can't use CLFHSI. 71*9880d681SAndroid Build Coastguard Workerdefine double @f6(double %a, double %b, i32 *%ptr) { 72*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 73*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clfhsi 74*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 75*9880d681SAndroid Build Coastguard Worker %val = load i32 , i32 *%ptr 76*9880d681SAndroid Build Coastguard Worker %cond = icmp eq i32 %val, 65536 77*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 78*9880d681SAndroid Build Coastguard Worker ret double %res 79*9880d681SAndroid Build Coastguard Worker} 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker; Check the high end of the CLFHSI range. 82*9880d681SAndroid Build Coastguard Workerdefine double @f7(double %a, double %b, i32 %i1, i32 *%base) { 83*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 84*9880d681SAndroid Build Coastguard Worker; CHECK: clfhsi 4092(%r3), 1 85*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 86*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 87*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 88*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 1023 89*9880d681SAndroid Build Coastguard Worker %val = load i32 , i32 *%ptr 90*9880d681SAndroid Build Coastguard Worker %cond = icmp ugt i32 %val, 1 91*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 92*9880d681SAndroid Build Coastguard Worker ret double %res 93*9880d681SAndroid Build Coastguard Worker} 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker; Check the next word up, which needs separate address logic, 96*9880d681SAndroid Build Coastguard Workerdefine double @f8(double %a, double %b, i32 *%base) { 97*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 98*9880d681SAndroid Build Coastguard Worker; CHECK: aghi %r2, 4096 99*9880d681SAndroid Build Coastguard Worker; CHECK: clfhsi 0(%r2), 1 100*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 101*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 102*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 103*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 1024 104*9880d681SAndroid Build Coastguard Worker %val = load i32 , i32 *%ptr 105*9880d681SAndroid Build Coastguard Worker %cond = icmp ugt i32 %val, 1 106*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 107*9880d681SAndroid Build Coastguard Worker ret double %res 108*9880d681SAndroid Build Coastguard Worker} 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Worker; Check negative offsets, which also need separate address logic. 111*9880d681SAndroid Build Coastguard Workerdefine double @f9(double %a, double %b, i32 *%base) { 112*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9: 113*9880d681SAndroid Build Coastguard Worker; CHECK: aghi %r2, -4 114*9880d681SAndroid Build Coastguard Worker; CHECK: clfhsi 0(%r2), 1 115*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 116*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 117*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 118*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 -1 119*9880d681SAndroid Build Coastguard Worker %val = load i32 , i32 *%ptr 120*9880d681SAndroid Build Coastguard Worker %cond = icmp ugt i32 %val, 1 121*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 122*9880d681SAndroid Build Coastguard Worker ret double %res 123*9880d681SAndroid Build Coastguard Worker} 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Worker; Check that CLFHSI does not allow indices. 126*9880d681SAndroid Build Coastguard Workerdefine double @f10(double %a, double %b, i64 %base, i64 %index) { 127*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10: 128*9880d681SAndroid Build Coastguard Worker; CHECK: agr {{%r2, %r3|%r3, %r2}} 129*9880d681SAndroid Build Coastguard Worker; CHECK: clfhsi 0({{%r[23]}}), 1 130*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 131*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 132*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 133*9880d681SAndroid Build Coastguard Worker %add = add i64 %base, %index 134*9880d681SAndroid Build Coastguard Worker %ptr = inttoptr i64 %add to i32 * 135*9880d681SAndroid Build Coastguard Worker %val = load i32 , i32 *%ptr 136*9880d681SAndroid Build Coastguard Worker %cond = icmp ugt i32 %val, 1 137*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 138*9880d681SAndroid Build Coastguard Worker ret double %res 139*9880d681SAndroid Build Coastguard Worker} 140