1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple powerpc64le < %s | FileCheck %s 3 4; Check constrained ops converted to call 5define void @test(ptr %cast) strictfp { 6; CHECK-LABEL: test: 7; CHECK: # %bb.0: # %root 8; CHECK-NEXT: mflr 0 9; CHECK-NEXT: .cfi_def_cfa_offset 64 10; CHECK-NEXT: .cfi_offset lr, 16 11; CHECK-NEXT: .cfi_offset r29, -24 12; CHECK-NEXT: .cfi_offset r30, -16 13; CHECK-NEXT: std 29, -24(1) # 8-byte Folded Spill 14; CHECK-NEXT: std 30, -16(1) # 8-byte Folded Spill 15; CHECK-NEXT: stdu 1, -64(1) 16; CHECK-NEXT: addi 30, 3, -8 17; CHECK-NEXT: li 29, 255 18; CHECK-NEXT: std 0, 80(1) 19; CHECK-NEXT: .p2align 5 20; CHECK-NEXT: .LBB0_1: # %for.body 21; CHECK-NEXT: # 22; CHECK-NEXT: lfdu 1, 8(30) 23; CHECK-NEXT: bl cos 24; CHECK-NEXT: nop 25; CHECK-NEXT: addi 29, 29, -1 26; CHECK-NEXT: stfd 1, 0(30) 27; CHECK-NEXT: cmpldi 29, 0 28; CHECK-NEXT: bc 12, 1, .LBB0_1 29; CHECK-NEXT: # %bb.2: # %exit 30; CHECK-NEXT: addi 1, 1, 64 31; CHECK-NEXT: ld 0, 16(1) 32; CHECK-NEXT: ld 30, -16(1) # 8-byte Folded Reload 33; CHECK-NEXT: ld 29, -24(1) # 8-byte Folded Reload 34; CHECK-NEXT: mtlr 0 35; CHECK-NEXT: blr 36root: 37 br label %for.body 38 39exit: 40 ret void 41 42for.body: 43 %i = phi i64 [ 0, %root ], [ %next, %for.body ] 44 %idx = getelementptr inbounds double, ptr %cast, i64 %i 45 %val = load double, ptr %idx 46 %cos = tail call nnan ninf nsz arcp double @llvm.experimental.constrained.cos.f64(double %val, metadata !"round.dynamic", metadata !"fpexcept.strict") 47 store double %cos, ptr %idx, align 8 48 %next = add nuw nsw i64 %i, 1 49 %cond = icmp eq i64 %next, 255 50 br i1 %cond, label %exit, label %for.body 51} 52 53; Check constrained ops converted to native instruction 54define void @test2(ptr %cast) strictfp { 55; CHECK-LABEL: test2: 56; CHECK: # %bb.0: # %entry 57; CHECK-NEXT: li 4, 255 58; CHECK-NEXT: addi 3, 3, -8 59; CHECK-NEXT: mtctr 4 60; CHECK-NEXT: .p2align 4 61; CHECK-NEXT: .LBB1_1: # %for.body 62; CHECK-NEXT: # 63; CHECK-NEXT: lfdu 0, 8(3) 64; CHECK-NEXT: xssqrtdp 0, 0 65; CHECK-NEXT: stfd 0, 0(3) 66; CHECK-NEXT: bdnz .LBB1_1 67; CHECK-NEXT: # %bb.2: # %exit 68; CHECK-NEXT: blr 69entry: 70 br label %for.body 71 72for.body: 73 %i = phi i64 [ 0, %entry ], [ %next, %for.body ] 74 %idx = getelementptr inbounds double, ptr %cast, i64 %i 75 %val = load double, ptr %idx 76 %cos = tail call nnan ninf nsz arcp double @llvm.experimental.constrained.sqrt.f64(double %val, metadata !"round.dynamic", metadata !"fpexcept.strict") 77 store double %cos, ptr %idx, align 8 78 %next = add nuw nsw i64 %i, 1 79 %cond = icmp eq i64 %next, 255 80 br i1 %cond, label %exit, label %for.body 81 82exit: 83 ret void 84} 85 86; Check constrained ops converted to call 87define void @testTan(ptr %cast) strictfp { 88; CHECK-LABEL: testTan: 89; CHECK: # %bb.0: # %root 90; CHECK-NEXT: mflr 0 91; CHECK-NEXT: .cfi_def_cfa_offset 64 92; CHECK-NEXT: .cfi_offset lr, 16 93; CHECK-NEXT: .cfi_offset r29, -24 94; CHECK-NEXT: .cfi_offset r30, -16 95; CHECK-NEXT: std 29, -24(1) # 8-byte Folded Spill 96; CHECK-NEXT: std 30, -16(1) # 8-byte Folded Spill 97; CHECK-NEXT: stdu 1, -64(1) 98; CHECK-NEXT: addi 30, 3, -8 99; CHECK-NEXT: li 29, 255 100; CHECK-NEXT: std 0, 80(1) 101; CHECK-NEXT: .p2align 5 102; CHECK-NEXT: .LBB2_1: # %for.body 103; CHECK-NEXT: # 104; CHECK-NEXT: lfdu 1, 8(30) 105; CHECK-NEXT: bl tan 106; CHECK-NEXT: nop 107; CHECK-NEXT: addi 29, 29, -1 108; CHECK-NEXT: stfd 1, 0(30) 109; CHECK-NEXT: cmpldi 29, 0 110; CHECK-NEXT: bc 12, 1, .LBB2_1 111; CHECK-NEXT: # %bb.2: # %exit 112; CHECK-NEXT: addi 1, 1, 64 113; CHECK-NEXT: ld 0, 16(1) 114; CHECK-NEXT: ld 30, -16(1) # 8-byte Folded Reload 115; CHECK-NEXT: ld 29, -24(1) # 8-byte Folded Reload 116; CHECK-NEXT: mtlr 0 117; CHECK-NEXT: blr 118root: 119 br label %for.body 120 121exit: 122 ret void 123 124for.body: 125 %i = phi i64 [ 0, %root ], [ %next, %for.body ] 126 %idx = getelementptr inbounds double, ptr %cast, i64 %i 127 %val = load double, ptr %idx 128 %tan = tail call nnan ninf nsz arcp double @llvm.experimental.constrained.tan.f64(double %val, metadata !"round.dynamic", metadata !"fpexcept.strict") 129 store double %tan, ptr %idx, align 8 130 %next = add nuw nsw i64 %i, 1 131 %cond = icmp eq i64 %next, 255 132 br i1 %cond, label %exit, label %for.body 133} 134 135; Check constrained ops converted to call 136define void @testAtan2(ptr %cast1, ptr %cast2) strictfp { 137; CHECK-LABEL: testAtan2: 138; CHECK: # %bb.0: # %root 139; CHECK-NEXT: mflr 0 140; CHECK-NEXT: .cfi_def_cfa_offset 64 141; CHECK-NEXT: .cfi_offset lr, 16 142; CHECK-NEXT: .cfi_offset r28, -32 143; CHECK-NEXT: .cfi_offset r29, -24 144; CHECK-NEXT: .cfi_offset r30, -16 145; CHECK-NEXT: std 28, -32(1) # 8-byte Folded Spill 146; CHECK-NEXT: std 29, -24(1) # 8-byte Folded Spill 147; CHECK-NEXT: std 30, -16(1) # 8-byte Folded Spill 148; CHECK-NEXT: stdu 1, -64(1) 149; CHECK-NEXT: addi 30, 3, -8 150; CHECK-NEXT: addi 29, 4, -8 151; CHECK-NEXT: li 28, 255 152; CHECK-NEXT: std 0, 80(1) 153; CHECK-NEXT: .p2align 5 154; CHECK-NEXT: .LBB3_1: # %for.body 155; CHECK-NEXT: # 156; CHECK-NEXT: lfdu 2, 8(29) 157; CHECK-NEXT: lfdu 1, 8(30) 158; CHECK-NEXT: bl atan2 159; CHECK-NEXT: nop 160; CHECK-NEXT: addi 28, 28, -1 161; CHECK-NEXT: stfd 1, 0(30) 162; CHECK-NEXT: cmpldi 28, 0 163; CHECK-NEXT: bc 12, 1, .LBB3_1 164; CHECK-NEXT: # %bb.2: # %exit 165; CHECK-NEXT: addi 1, 1, 64 166; CHECK-NEXT: ld 0, 16(1) 167; CHECK-NEXT: ld 30, -16(1) # 8-byte Folded Reload 168; CHECK-NEXT: ld 29, -24(1) # 8-byte Folded Reload 169; CHECK-NEXT: ld 28, -32(1) # 8-byte Folded Reload 170; CHECK-NEXT: mtlr 0 171; CHECK-NEXT: blr 172root: 173 br label %for.body 174 175exit: 176 ret void 177 178for.body: 179 %i = phi i64 [ 0, %root ], [ %next, %for.body ] 180 %idx1 = getelementptr inbounds double, ptr %cast1, i64 %i 181 %idx2 = getelementptr inbounds double, ptr %cast2, i64 %i 182 %val1 = load double, ptr %idx1 183 %val2 = load double, ptr %idx2 184 %tan = tail call nnan ninf nsz arcp double @llvm.experimental.constrained.atan2.f64(double %val1, double %val2, metadata !"round.dynamic", metadata !"fpexcept.strict") 185 store double %tan, ptr %idx1, align 8 186 %next = add nuw nsw i64 %i, 1 187 %cond = icmp eq i64 %next, 255 188 br i1 %cond, label %exit, label %for.body 189} 190 191declare double @llvm.experimental.constrained.cos.f64(double, metadata, metadata) 192declare double @llvm.experimental.constrained.tan.f64(double, metadata, metadata) 193declare double @llvm.experimental.constrained.atan2.f64(double, double, metadata, metadata) 194declare double @llvm.experimental.constrained.sqrt.f64(double, metadata, metadata) 195