brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.2 KiB · 71974b0 Raw
267 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52; RUN: llc -mattr=+wide-arithmetic < %s | FileCheck %s3 4target triple = "wasm32-unknown-unknown"5 6define i128 @add_i128(i128 %a, i128 %b) {7; CHECK-LABEL: add_i128:8; CHECK:         .functype add_i128 (i32, i64, i64, i64, i64) -> ()9; CHECK-NEXT:  # %bb.0:10; CHECK-NEXT:    local.get 111; CHECK-NEXT:    local.get 212; CHECK-NEXT:    local.get 313; CHECK-NEXT:    local.get 414; CHECK-NEXT:    i64.add12815; CHECK-NEXT:    local.set 316; CHECK-NEXT:    local.set 417; CHECK-NEXT:    local.get 018; CHECK-NEXT:    local.get 319; CHECK-NEXT:    i64.store 820; CHECK-NEXT:    local.get 021; CHECK-NEXT:    local.get 422; CHECK-NEXT:    i64.store 023; CHECK-NEXT:    # fallthrough-return24  %c = add i128 %a, %b25  ret i128 %c26}27 28define i128 @sub_i128(i128 %a, i128 %b) {29; CHECK-LABEL: sub_i128:30; CHECK:         .functype sub_i128 (i32, i64, i64, i64, i64) -> ()31; CHECK-NEXT:  # %bb.0:32; CHECK-NEXT:    local.get 133; CHECK-NEXT:    local.get 234; CHECK-NEXT:    local.get 335; CHECK-NEXT:    local.get 436; CHECK-NEXT:    i64.sub12837; CHECK-NEXT:    local.set 338; CHECK-NEXT:    local.set 439; CHECK-NEXT:    local.get 040; CHECK-NEXT:    local.get 341; CHECK-NEXT:    i64.store 842; CHECK-NEXT:    local.get 043; CHECK-NEXT:    local.get 444; CHECK-NEXT:    i64.store 045; CHECK-NEXT:    # fallthrough-return46  %c = sub i128 %a, %b47  ret i128 %c48}49 50define i128 @mul_i128(i128 %a, i128 %b) {51; CHECK-LABEL: mul_i128:52; CHECK:         .functype mul_i128 (i32, i64, i64, i64, i64) -> ()53; CHECK-NEXT:    .local i6454; CHECK-NEXT:  # %bb.0:55; CHECK-NEXT:    local.get 056; CHECK-NEXT:    local.get 157; CHECK-NEXT:    local.get 358; CHECK-NEXT:    i64.mul_wide_u59; CHECK-NEXT:    local.set 560; CHECK-NEXT:    i64.store 061; CHECK-NEXT:    local.get 062; CHECK-NEXT:    local.get 563; CHECK-NEXT:    local.get 164; CHECK-NEXT:    local.get 465; CHECK-NEXT:    i64.mul66; CHECK-NEXT:    i64.add67; CHECK-NEXT:    local.get 268; CHECK-NEXT:    local.get 369; CHECK-NEXT:    i64.mul70; CHECK-NEXT:    i64.add71; CHECK-NEXT:    i64.store 872; CHECK-NEXT:    # fallthrough-return73  %c = mul i128 %a, %b74  ret i128 %c75}76 77define i128 @i64_mul_wide_s(i64 %a, i64 %b) {78; CHECK-LABEL: i64_mul_wide_s:79; CHECK:         .functype i64_mul_wide_s (i32, i64, i64) -> ()80; CHECK-NEXT:  # %bb.0:81; CHECK-NEXT:    local.get 182; CHECK-NEXT:    local.get 283; CHECK-NEXT:    i64.mul_wide_s84; CHECK-NEXT:    local.set 185; CHECK-NEXT:    local.set 286; CHECK-NEXT:    local.get 087; CHECK-NEXT:    local.get 188; CHECK-NEXT:    i64.store 889; CHECK-NEXT:    local.get 090; CHECK-NEXT:    local.get 291; CHECK-NEXT:    i64.store 092; CHECK-NEXT:    # fallthrough-return93  %a128 = sext i64 %a to i12894  %b128 = sext i64 %b to i12895  %c = mul i128 %a128, %b12896  ret i128 %c97}98 99define i128 @i64_mul_wide_u(i64 %a, i64 %b) {100; CHECK-LABEL: i64_mul_wide_u:101; CHECK:         .functype i64_mul_wide_u (i32, i64, i64) -> ()102; CHECK-NEXT:  # %bb.0:103; CHECK-NEXT:    local.get 1104; CHECK-NEXT:    local.get 2105; CHECK-NEXT:    i64.mul_wide_u106; CHECK-NEXT:    local.set 1107; CHECK-NEXT:    local.set 2108; CHECK-NEXT:    local.get 0109; CHECK-NEXT:    local.get 1110; CHECK-NEXT:    i64.store 8111; CHECK-NEXT:    local.get 0112; CHECK-NEXT:    local.get 2113; CHECK-NEXT:    i64.store 0114; CHECK-NEXT:    # fallthrough-return115  %a128 = zext i64 %a to i128116  %b128 = zext i64 %b to i128117  %c = mul i128 %a128, %b128118  ret i128 %c119}120 121define i64 @mul_i128_only_lo(i128 %a, i128 %b) {122; CHECK-LABEL: mul_i128_only_lo:123; CHECK:         .functype mul_i128_only_lo (i64, i64, i64, i64) -> (i64)124; CHECK-NEXT:  # %bb.0:125; CHECK-NEXT:    local.get 0126; CHECK-NEXT:    local.get 2127; CHECK-NEXT:    i64.mul128; CHECK-NEXT:    # fallthrough-return129  %c = mul i128 %a, %b130  %d = trunc i128 %c to i64131  ret i64 %d132}133 134declare { i64, i1 } @llvm.sadd.with.overflow.i64(i64, i64)135declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i64)136 137; This is a codegen test to see the effect of overflowing adds on signed138; integers with wide-arithmetic enabled. At this time it doesn't actually139; generate anything differently than without wide-arithmetic but this has also140; been useful for evaluating the proposal.141define { i64, i1 } @add_wide_s(i64 %a, i64 %b) {142; CHECK-LABEL: add_wide_s:143; CHECK:         .functype add_wide_s (i32, i64, i64) -> ()144; CHECK-NEXT:    .local i64145; CHECK-NEXT:  # %bb.0:146; CHECK-NEXT:    local.get 0147; CHECK-NEXT:    local.get 1148; CHECK-NEXT:    local.get 2149; CHECK-NEXT:    i64.add150; CHECK-NEXT:    local.tee 3151; CHECK-NEXT:    i64.store 0152; CHECK-NEXT:    local.get 0153; CHECK-NEXT:    local.get 2154; CHECK-NEXT:    i64.const 0155; CHECK-NEXT:    i64.lt_s156; CHECK-NEXT:    local.get 3157; CHECK-NEXT:    local.get 1158; CHECK-NEXT:    i64.lt_s159; CHECK-NEXT:    i32.xor160; CHECK-NEXT:    i32.store8 8161; CHECK-NEXT:    # fallthrough-return162  %pair = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)163  ret { i64, i1 } %pair164}165 166define { i64, i1 } @add_wide_u(i64 %a, i64 %b) {167; CHECK-LABEL: add_wide_u:168; CHECK:         .functype add_wide_u (i32, i64, i64) -> ()169; CHECK-NEXT:  # %bb.0:170; CHECK-NEXT:    local.get 1171; CHECK-NEXT:    i64.const 0172; CHECK-NEXT:    local.get 2173; CHECK-NEXT:    i64.const 0174; CHECK-NEXT:    i64.add128175; CHECK-NEXT:    local.set 1176; CHECK-NEXT:    local.set 2177; CHECK-NEXT:    local.get 0178; CHECK-NEXT:    local.get 1179; CHECK-NEXT:    i64.store8 8180; CHECK-NEXT:    local.get 0181; CHECK-NEXT:    local.get 2182; CHECK-NEXT:    i64.store 0183; CHECK-NEXT:    # fallthrough-return184  %pair = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)185  ret { i64, i1 } %pair186}187 188; This is a model of a hypothetical `i64.add_wide3_u` instruction using LLVM189; intrinsics. In theory this should optimize better (to the equivalent below)190; but it doesn't currently.191define { i64, i64 } @add_wide3_u_via_intrinsics(i64 %a, i64 %b, i64 %c) {192; CHECK-LABEL: add_wide3_u_via_intrinsics:193; CHECK:         .functype add_wide3_u_via_intrinsics (i32, i64, i64, i64) -> ()194; CHECK-NEXT:  # %bb.0:195; CHECK-NEXT:    local.get 0196; CHECK-NEXT:    local.get 1197; CHECK-NEXT:    i64.const 0198; CHECK-NEXT:    local.get 2199; CHECK-NEXT:    i64.const 0200; CHECK-NEXT:    i64.add128201; CHECK-NEXT:    local.set 2202; CHECK-NEXT:    i64.const 0203; CHECK-NEXT:    local.get 3204; CHECK-NEXT:    i64.const 0205; CHECK-NEXT:    i64.add128206; CHECK-NEXT:    local.set 1207; CHECK-NEXT:    i64.store 0208; CHECK-NEXT:    local.get 0209; CHECK-NEXT:    local.get 2210; CHECK-NEXT:    local.get 1211; CHECK-NEXT:    i64.add212; CHECK-NEXT:    i64.store 8213; CHECK-NEXT:    # fallthrough-return214  %pair = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)215  %t0 = extractvalue { i64, i1 } %pair, 0216  %carry1 = extractvalue { i64, i1 } %pair, 1217 218  %pair2 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %t0, i64 %c)219  %ret1 = extractvalue { i64, i1 } %pair2, 0220  %carry2 = extractvalue { i64, i1 } %pair2, 1221 222  %carry1_64 = zext i1 %carry1 to i64223  %carry2_64 = zext i1 %carry2 to i64224  %ret2 = add i64 %carry1_64, %carry2_64225 226  %r0 = insertvalue { i64, i64 } poison, i64 %ret1, 0227  %r1 = insertvalue { i64, i64 } %r0, i64 %ret2, 1228  ret { i64, i64 } %r1229}230 231; This is a model of a hypothetical `i64.add_wide3_u` instruction using 128-bit232; integer addition. This optimizes better than the above currently.233define { i64, i64 } @add_wide3_u_via_i128(i64 %a, i64 %b, i64 %c) {234; CHECK-LABEL: add_wide3_u_via_i128:235; CHECK:         .functype add_wide3_u_via_i128 (i32, i64, i64, i64) -> ()236; CHECK-NEXT:  # %bb.0:237; CHECK-NEXT:    local.get 1238; CHECK-NEXT:    i64.const 0239; CHECK-NEXT:    local.get 2240; CHECK-NEXT:    i64.const 0241; CHECK-NEXT:    i64.add128242; CHECK-NEXT:    local.get 3243; CHECK-NEXT:    i64.const 0244; CHECK-NEXT:    i64.add128245; CHECK-NEXT:    local.set 1246; CHECK-NEXT:    local.set 2247; CHECK-NEXT:    local.get 0248; CHECK-NEXT:    local.get 1249; CHECK-NEXT:    i64.store 8250; CHECK-NEXT:    local.get 0251; CHECK-NEXT:    local.get 2252; CHECK-NEXT:    i64.store 0253; CHECK-NEXT:    # fallthrough-return254  %a128 = zext i64 %a to i128255  %b128 = zext i64 %b to i128256  %c128 = zext i64 %c to i128257  %t0 = add i128 %a128, %b128258  %t1 = add i128 %t0, %c128259  %result = trunc i128 %t1 to i64260  %t2 = lshr i128 %t1, 64261  %carry = trunc i128 %t2 to i64262 263  %ret0 = insertvalue { i64, i64 } poison, i64 %result, 0264  %ret1 = insertvalue { i64, i64 } %ret0, i64 %carry, 1265  ret { i64, i64 } %ret1266}267