brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · 6bc7fb8 Raw
253 lines · plain
1; Test 32-bit signed division and remainder.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu -asm-verbose=0 | FileCheck %s4 5declare i32 @foo()6 7; Test register division.  The result is in the second of the two registers.8define void @f1(ptr %dest, i32 %a, i32 %b) {9; CHECK-LABEL: f1:10; CHECK: lgfr %r1, %r311; CHECK: dsgfr %r0, %r412; CHECK: st %r1, 0(%r2)13; CHECK: br %r1414  %div = sdiv i32 %a, %b15  store i32 %div, ptr %dest16  ret void17}18 19; Test register remainder.  The result is in the first of the two registers.20define void @f2(ptr %dest, i32 %a, i32 %b) {21; CHECK-LABEL: f2:22; CHECK: lgfr %r1, %r323; CHECK: dsgfr %r0, %r424; CHECK: st %r0, 0(%r2)25; CHECK: br %r1426  %rem = srem i32 %a, %b27  store i32 %rem, ptr %dest28  ret void29}30 31; Test that division and remainder use a single instruction.32define i32 @f3(i32 %dummy, i32 %a, i32 %b) {33; CHECK-LABEL: f3:34; CHECK-NOT: %r235; CHECK: lgfr %r3, %r336; CHECK-NOT: %r237; CHECK: dsgfr %r2, %r438; CHECK-NOT: dsgfr39; CHECK: or %r2, %r340; CHECK: br %r1441  %div = sdiv i32 %a, %b42  %rem = srem i32 %a, %b43  %or = or i32 %rem, %div44  ret i32 %or45}46 47; Check that the sign extension of the dividend is elided when the argument48; is already sign-extended.49define i32 @f4(i32 %dummy, i32 signext %a, i32 %b) {50; CHECK-LABEL: f4:51; CHECK-NOT: {{%r[234]}}52; CHECK: dsgfr %r2, %r453; CHECK-NOT: dsgfr54; CHECK: or %r3, %r255; CHECK: lr %r2, %r356; CHECK: br %r1457  %div = sdiv i32 %a, %b58  %rem = srem i32 %a, %b59  %or = or i32 %rem, %div60  ret i32 %or61}62 63; Test that memory dividends are loaded using sign extension (LGF).64define i32 @f5(i32 %dummy, ptr %src, i32 %b) {65; CHECK-LABEL: f5:66; CHECK-NOT: %r267; CHECK: lgf %r3, 0(%r3)68; CHECK-NOT: %r269; CHECK: dsgfr %r2, %r470; CHECK-NOT: dsgfr71; CHECK: or %r2, %r372; CHECK: br %r1473  %a = load i32, ptr %src74  %div = sdiv i32 %a, %b75  %rem = srem i32 %a, %b76  %or = or i32 %rem, %div77  ret i32 %or78}79 80; Test memory division with no displacement.81define void @f6(ptr %dest, i32 %a, ptr %src) {82; CHECK-LABEL: f6:83; CHECK: lgfr %r1, %r384; CHECK: dsgf %r0, 0(%r4)85; CHECK: st %r1, 0(%r2)86; CHECK: br %r1487  %b = load i32, ptr %src88  %div = sdiv i32 %a, %b89  store i32 %div, ptr %dest90  ret void91}92 93; Test memory remainder with no displacement.94define void @f7(ptr %dest, i32 %a, ptr %src) {95; CHECK-LABEL: f7:96; CHECK: lgfr %r1, %r397; CHECK: dsgf %r0, 0(%r4)98; CHECK: st %r0, 0(%r2)99; CHECK: br %r14100  %b = load i32, ptr %src101  %rem = srem i32 %a, %b102  store i32 %rem, ptr %dest103  ret void104}105 106; Test both memory division and memory remainder.107define i32 @f8(i32 %dummy, i32 %a, ptr %src) {108; CHECK-LABEL: f8:109; CHECK-NOT: %r2110; CHECK: lgfr %r3, %r3111; CHECK-NOT: %r2112; CHECK: dsgf %r2, 0(%r4)113; CHECK-NOT: {{dsgf|dsgfr}}114; CHECK: or %r2, %r3115; CHECK: br %r14116  %b = load i32, ptr %src117  %div = sdiv i32 %a, %b118  %rem = srem i32 %a, %b119  %or = or i32 %rem, %div120  ret i32 %or121}122 123; Check the high end of the DSGF range.124define i32 @f9(i32 %dummy, i32 %a, ptr %src) {125; CHECK-LABEL: f9:126; CHECK: dsgf %r2, 524284(%r4)127; CHECK: br %r14128  %ptr = getelementptr i32, ptr %src, i64 131071129  %b = load i32, ptr %ptr130  %rem = srem i32 %a, %b131  ret i32 %rem132}133 134; Check the next word up, which needs separate address logic.135; Other sequences besides this one would be OK.136define i32 @f10(i32 %dummy, i32 %a, ptr %src) {137; CHECK-LABEL: f10:138; CHECK: agfi %r4, 524288139; CHECK: dsgf %r2, 0(%r4)140; CHECK: br %r14141  %ptr = getelementptr i32, ptr %src, i64 131072142  %b = load i32, ptr %ptr143  %rem = srem i32 %a, %b144  ret i32 %rem145}146 147; Check the high end of the negative aligned DSGF range.148define i32 @f11(i32 %dummy, i32 %a, ptr %src) {149; CHECK-LABEL: f11:150; CHECK: dsgf %r2, -4(%r4)151; CHECK: br %r14152  %ptr = getelementptr i32, ptr %src, i64 -1153  %b = load i32, ptr %ptr154  %rem = srem i32 %a, %b155  ret i32 %rem156}157 158; Check the low end of the DSGF range.159define i32 @f12(i32 %dummy, i32 %a, ptr %src) {160; CHECK-LABEL: f12:161; CHECK: dsgf %r2, -524288(%r4)162; CHECK: br %r14163  %ptr = getelementptr i32, ptr %src, i64 -131072164  %b = load i32, ptr %ptr165  %rem = srem i32 %a, %b166  ret i32 %rem167}168 169; Check the next word down, which needs separate address logic.170; Other sequences besides this one would be OK.171define i32 @f13(i32 %dummy, i32 %a, ptr %src) {172; CHECK-LABEL: f13:173; CHECK: agfi %r4, -524292174; CHECK: dsgf %r2, 0(%r4)175; CHECK: br %r14176  %ptr = getelementptr i32, ptr %src, i64 -131073177  %b = load i32, ptr %ptr178  %rem = srem i32 %a, %b179  ret i32 %rem180}181 182; Check that DSGF allows an index.183define i32 @f14(i32 %dummy, i32 %a, i64 %src, i64 %index) {184; CHECK-LABEL: f14:185; CHECK: dsgf %r2, 524287(%r5,%r4)186; CHECK: br %r14187  %add1 = add i64 %src, %index188  %add2 = add i64 %add1, 524287189  %ptr = inttoptr i64 %add2 to ptr190  %b = load i32, ptr %ptr191  %rem = srem i32 %a, %b192  ret i32 %rem193}194 195; Make sure that we still use DSGFR rather than DSGR in cases where196; a load and division cannot be combined.197define void @f15(ptr %dest, ptr %src) {198; CHECK-LABEL: f15:199; CHECK: l [[B:%r[0-9]+]], 0(%r3)200; CHECK: brasl %r14, foo@PLT201; CHECK: lgfr %r1, %r2202; CHECK: dsgfr %r0, [[B]]203; CHECK: br %r14204  %b = load i32, ptr %src205  %a = call i32 @foo()206  %div = sdiv i32 %a, %b207  store i32 %div, ptr %dest208  ret void209}210 211; Check that divisions of spilled values can use DSGF rather than DSGFR.212define i32 @f16(ptr %ptr0) {213; CHECK-LABEL: f16:214; CHECK: brasl %r14, foo@PLT215; CHECK: dsgf {{%r[0-9]+}}, 16{{[04]}}(%r15)216; CHECK: br %r14217  %ptr1 = getelementptr i32, ptr %ptr0, i64 2218  %ptr2 = getelementptr i32, ptr %ptr0, i64 4219  %ptr3 = getelementptr i32, ptr %ptr0, i64 6220  %ptr4 = getelementptr i32, ptr %ptr0, i64 8221  %ptr5 = getelementptr i32, ptr %ptr0, i64 10222  %ptr6 = getelementptr i32, ptr %ptr0, i64 12223  %ptr7 = getelementptr i32, ptr %ptr0, i64 14224  %ptr8 = getelementptr i32, ptr %ptr0, i64 16225  %ptr9 = getelementptr i32, ptr %ptr0, i64 18226 227  %val0 = load i32, ptr %ptr0228  %val1 = load i32, ptr %ptr1229  %val2 = load i32, ptr %ptr2230  %val3 = load i32, ptr %ptr3231  %val4 = load i32, ptr %ptr4232  %val5 = load i32, ptr %ptr5233  %val6 = load i32, ptr %ptr6234  %val7 = load i32, ptr %ptr7235  %val8 = load i32, ptr %ptr8236  %val9 = load i32, ptr %ptr9237 238  %ret = call i32 @foo()239 240  %div0 = sdiv i32 %ret, %val0241  %div1 = sdiv i32 %div0, %val1242  %div2 = sdiv i32 %div1, %val2243  %div3 = sdiv i32 %div2, %val3244  %div4 = sdiv i32 %div3, %val4245  %div5 = sdiv i32 %div4, %val5246  %div6 = sdiv i32 %div5, %val6247  %div7 = sdiv i32 %div6, %val7248  %div8 = sdiv i32 %div7, %val8249  %div9 = sdiv i32 %div8, %val9250 251  ret i32 %div9252}253