From f0825587ec9b690fa4376a9dfa1c43a6e183ae7b Mon Sep 17 00:00:00 2001 From: Lucas Ste <38472950+LucasSte@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:10:23 -0300 Subject: [PATCH] [SOL] Fix ALU32 instructions with explicit sign extension (#116) --- llvm/lib/Target/SBF/SBFISelLowering.cpp | 45 ++++-- llvm/lib/Target/SBF/SBFInstrInfo.td | 6 + llvm/lib/Target/SBF/SBFSubtarget.cpp | 3 +- llvm/lib/Target/SBF/SBFTargetMachine.cpp | 8 +- .../CodeGen/SBF/32-bit-subreg-cond-select.ll | 16 ++- llvm/test/CodeGen/SBF/atomics_sbf.ll | 76 +++++------ llvm/test/CodeGen/SBF/br_cc_sext.ll | 129 ++++++++++++++++++ llvm/test/CodeGen/SBF/remove_truncate_7.ll | 2 +- 8 files changed, 227 insertions(+), 58 deletions(-) create mode 100644 llvm/test/CodeGen/SBF/br_cc_sext.ll diff --git a/llvm/lib/Target/SBF/SBFISelLowering.cpp b/llvm/lib/Target/SBF/SBFISelLowering.cpp index 6eb5dd3640cf90..4979d552e83364 100644 --- a/llvm/lib/Target/SBF/SBFISelLowering.cpp +++ b/llvm/lib/Target/SBF/SBFISelLowering.cpp @@ -126,7 +126,11 @@ SBFTargetLowering::SBFTargetLowering(const TargetMachine &TM, if (STI.getHasAlu32()) { setOperationAction(ISD::BSWAP, MVT::i32, Promote); - setOperationAction(ISD::BR_CC, MVT::i32, Promote); + setOperationAction(ISD::BR_CC, MVT::i32, Custom); + setOperationAction(ISD::CTTZ, MVT::i32, Expand); + setOperationAction(ISD::CTLZ, MVT::i32, Expand); + setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand); + setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand); } setOperationAction(ISD::CTTZ, MVT::i64, Expand); @@ -763,6 +767,30 @@ SDValue SBFTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { if (!getHasJmpExt()) NegateCC(LHS, RHS, CC); + bool IsSignedCmp = (CC == ISD::SETGT || + CC == ISD::SETGE || + CC == ISD::SETLT || + CC == ISD::SETLE); + bool Is32Num = LHS.getValueType() == MVT::i32 || + RHS.getValueType() == MVT::i32; + + if (getHasAlu32() && Is32Num) { + if (isIntOrFPConstant(RHS) || isIntOrFPConstant(LHS)) { + // Immediate values are sign extended in SBF, so we sign extend the + // registers for a correct comparison. + LHS = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, LHS); + RHS = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, RHS); + } else if (IsSignedCmp) { + // If the comparison is signed, we sign extend registers + LHS = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, LHS); + RHS = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, RHS); + } else { + // If the comparison is unsigned, we zero extend registers + LHS = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, LHS); + RHS = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, RHS); + } + } + return DAG.getNode(SBFISD::BR_CC, DL, Op.getValueType(), Chain, LHS, RHS, DAG.getConstant(CC, DL, MVT::i64), Dest); } @@ -941,7 +969,7 @@ SBFTargetLowering::EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB, if (!isSigned) { unsigned MovOp = Subtarget->getHasExplicitSignExt() - ? SBF::MOV_rr : SBF::MOV_32_64; + ? SBF::MOV_32_64_no_sext : SBF::MOV_32_64; Register PromotedReg0 = RegInfo.createVirtualRegister(RC); BuildMI(BB, DL, TII.get(MovOp), PromotedReg0).addReg(Reg); return PromotedReg0; @@ -1087,15 +1115,12 @@ SBFTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, CC == ISD::SETLT || CC == ISD::SETLE); - // eBPF at the moment only has 64-bit comparison. Any 32-bit comparison need - // to be promoted, however if the 32-bit comparison operands are destination - // registers then they are implicitly zero-extended already, there is no - // need of explicit zero-extend sequence for them. - // - // We simply do extension for all situations in this method, but we will - // try to remove those unnecessary in SBFMIPeephole pass. + // SBF at the moment only has 64-bit comparison. Any 32-bit comparison needs + // to be promoted. If we are comparing against an immediate value, we must + // sign extend the registers. Likewise for signed comparisons. Unsigned + // comparisons will zero extent registers. if (is32BitCmp) - LHS = EmitSubregExt(MI, BB, LHS, isSignedCmp); + LHS = EmitSubregExt(MI, BB, LHS, isSignedCmp || !isSelectRROp); if (isSelectRROp) { Register RHS = MI.getOperand(2).getReg(); diff --git a/llvm/lib/Target/SBF/SBFInstrInfo.td b/llvm/lib/Target/SBF/SBFInstrInfo.td index 03136325cdca08..a2a41da9e0f779 100644 --- a/llvm/lib/Target/SBF/SBFInstrInfo.td +++ b/llvm/lib/Target/SBF/SBFInstrInfo.td @@ -1015,6 +1015,12 @@ let isCodeGenOnly = 1 in { def MOV_32_64_addr : MATH_RI, Requires<[SBFNoLddw]>; + + def MOV_32_64_no_sext : MATH_RR; } let DecoderNamespace = "SBFv2", Predicates = [SBFNoLddw] in { diff --git a/llvm/lib/Target/SBF/SBFSubtarget.cpp b/llvm/lib/Target/SBF/SBFSubtarget.cpp index 313be03f9539e4..f6e8c84c46a180 100644 --- a/llvm/lib/Target/SBF/SBFSubtarget.cpp +++ b/llvm/lib/Target/SBF/SBFSubtarget.cpp @@ -37,7 +37,6 @@ SBFSubtarget &SBFSubtarget::initializeSubtargetDependencies(const Triple &TT, void SBFSubtarget::initializeEnvironment(const Triple &TT) { assert(TT.getArch() == Triple::sbf && "expected Triple::sbf"); HasJmpExt = false; - HasAlu32 = false; UseDwarfRIS = false; // SBFv2 features @@ -49,6 +48,8 @@ void SBFSubtarget::initializeEnvironment(const Triple &TT) { HasPqrClass = false; NewCallConvention = false; HasStoreImm = false; + HasAlu32 = false; + HasExplicitSignExt = false; } void SBFSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { diff --git a/llvm/lib/Target/SBF/SBFTargetMachine.cpp b/llvm/lib/Target/SBF/SBFTargetMachine.cpp index 20f1de30d04f47..ced3cd528d8957 100644 --- a/llvm/lib/Target/SBF/SBFTargetMachine.cpp +++ b/llvm/lib/Target/SBF/SBFTargetMachine.cpp @@ -158,10 +158,12 @@ void SBFPassConfig::addMachineSSAOptimization() { // Peephole ran at last. TargetPassConfig::addMachineSSAOptimization(); - const SBFSubtarget *Subtarget = getSBFTargetMachine().getSubtargetImpl(); +// const SBFSubtarget *Subtarget = getSBFTargetMachine().getSubtargetImpl(); if (!DisableMIPeephole) { - if (Subtarget->getHasAlu32()) - addPass(createSBFMIPeepholePass()); +// TODO: The peephole doesn't work with explicit sign extension. A future PR +// will revamp the implementation. +// if (Subtarget->getHasAlu32()) +// addPass(createSBFMIPeepholePass()); addPass(createSBFMIPeepholeTruncElimPass()); } } diff --git a/llvm/test/CodeGen/SBF/32-bit-subreg-cond-select.ll b/llvm/test/CodeGen/SBF/32-bit-subreg-cond-select.ll index 2ea3048a314e28..af88048ccf37f7 100644 --- a/llvm/test/CodeGen/SBF/32-bit-subreg-cond-select.ll +++ b/llvm/test/CodeGen/SBF/32-bit-subreg-cond-select.ll @@ -1,4 +1,4 @@ -; RUN: llc -O2 -march=sbf -mattr=+alu32 < %s | FileCheck %s +; RUN: llc -O2 -march=sbf -mattr=+alu32,+explicit-sext -verify-machineinstrs < %s | FileCheck %s ; ; unsigned int select_cc_32 (unsigned a, unsigned b, int c, int d) ; { @@ -56,19 +56,23 @@ entry: ret i32 %c.d } ; CHECK-LABEL: select_cc_32 -; CHECK: mov32 r{{[0-9]+}}, w{{[0-9]+}} +; CHECK: mov64 r{{[0-9]+}}, w{{[0-9]+}} +; CHECK: mov64 r{{[0-9]+}}, w{{[0-9]+}} +; CHECK: jgt r{{[0-9]+}}, r{{[0-9]+}} ; CHECK-NOT: lsh64 r{{[0-9]+}}, 32 ; CHECK-NOT: rsh64 r{{[0-9]+}}, 32 ; Function Attrs: norecurse nounwind readnone define dso_local i64 @select_cc_32_64(i32 %a, i32 %b, i64 %c, i64 %d) local_unnamed_addr #0 { entry: - %cmp = icmp ugt i32 %a, %b + %cmp = icmp sgt i32 %a, %b %c.d = select i1 %cmp, i64 %c, i64 %d ret i64 %c.d } ; CHECK-LABEL: select_cc_32_64 ; CHECK: mov32 r{{[0-9]+}}, w{{[0-9]+}} +; CHECK: mov32 r{{[0-9]+}}, w{{[0-9]+}} +; CHECK: jsgt r{{[0-9]+}}, r{{[0-9]+}} ; CHECK-NOT: lsh64 r{{[0-9]+}}, 32 ; CHECK-NOT: rsh64 r{{[0-9]+}}, 32 @@ -80,6 +84,7 @@ entry: ret i32 %c.d } ; CHECK-LABEL: select_cc_64_32 +; CHECK: jsgt r{{[0-9]+}}, r{{[0-9]+}} ; CHECK-NOT: lsh64 r{{[0-9]+}}, 32 ; Function Attrs: norecurse nounwind readnone @@ -91,18 +96,20 @@ entry: } ; CHECK-LABEL: selecti_cc_32 ; CHECK: mov32 r{{[0-9]+}}, w{{[0-9]+}} +; CHECK: jgt r{{[0-9]+}}, 10 ; CHECK-NOT: lsh64 r{{[0-9]+}}, 32 ; CHECK-NOT: rsh64 r{{[0-9]+}}, 32 ; Function Attrs: norecurse nounwind readnone define dso_local i64 @selecti_cc_32_64(i32 %a, i64 %c, i64 %d) local_unnamed_addr #0 { entry: - %cmp = icmp ugt i32 %a, 11 + %cmp = icmp sgt i32 %a, 11 %c.d = select i1 %cmp, i64 %c, i64 %d ret i64 %c.d } ; CHECK-LABEL: selecti_cc_32_64 ; CHECK: mov32 r{{[0-9]+}}, w{{[0-9]+}} +; CHECK: jsgt r{{[0-9]+}}, 11, ; CHECK-NOT: lsh64 r{{[0-9]+}}, 32 ; CHECK-NOT: rsh64 r{{[0-9]+}}, 32 @@ -114,4 +121,5 @@ entry: ret i32 %c.d } ; CHECK-LABEL: selecti_cc_64_32 +; CHECK: jsgt r{{[0-9]+}}, 12 ; CHECK-NOT: lsh64 r{{[0-9]+}}, 32 diff --git a/llvm/test/CodeGen/SBF/atomics_sbf.ll b/llvm/test/CodeGen/SBF/atomics_sbf.ll index 9e135c44664ddf..7c1b599e63b78c 100644 --- a/llvm/test/CodeGen/SBF/atomics_sbf.ll +++ b/llvm/test/CodeGen/SBF/atomics_sbf.ll @@ -1,8 +1,8 @@ -; RUN: llc < %s -march=sbf -mcpu=v3 -verify-machineinstrs | tee -i /tmp/log | FileCheck %s +; RUN: llc < %s -march=sbf -mattr=+alu32,+explicit-sext -verify-machineinstrs | tee -i /tmp/log | FileCheck %s ; ; CHECK-LABEL: test_load_add_32 ; CHECK: ldxw w0, [r1 + 0] -; CHECK: mov32 w3, w0 +; CHECK: mov64 w3, w0 ; CHECK: add32 w3, w2 ; CHECK: stxw [r1 + 0], w3 define dso_local i32 @test_load_add_32(i32* nocapture %p, i32 %v) local_unnamed_addr { @@ -25,7 +25,7 @@ entry: ; CHECK-LABEL: test_load_sub_32 ; CHECK: ldxw w0, [r1 + 0] -; CHECK: mov32 w3, w0 +; CHECK: mov64 w3, w0 ; CHECK: sub32 w3, w2 ; CHECK: stxw [r1 + 0], w3 define dso_local i32 @test_load_sub_32(i32* nocapture %p, i32 %v) local_unnamed_addr { @@ -67,8 +67,10 @@ entry: ; CHECK-LABEL: test_cas_32 ; CHECK: ldxw w0, [r1 + 0] -; CHECK: jeq r0, r2, -; CHECK: mov32 w3, w0 +; CHECK: mov64 r4, w0 +; CHECK: mov64 r2, w2 +; CHECK: jeq r4, r2, +; CHECK: mov64 w3, w0 ; CHECK: stxw [r1 + 0], w3 define dso_local i32 @test_cas_32(i32* nocapture %p, i32 %old, i32 %new) local_unnamed_addr { entry: @@ -91,7 +93,7 @@ entry: ; CHECK-LABEL: test_load_and_32 ; CHECK: ldxw w0, [r1 + 0] -; CHECK: mov32 w3, w0 +; CHECK: mov64 w3, w0 ; CHECK: and32 w3, w2 ; CHECK: stxw [r1 + 0], w3 define dso_local i32 @test_load_and_32(i32* nocapture %p, i32 %v) local_unnamed_addr { @@ -113,7 +115,7 @@ entry: ; CHECK-LABEL: test_load_nand_32 ; CHECK: ldxw w0, [r1 + 0] -; CHECK: mov32 w3, w0 +; CHECK: mov64 w3, w0 ; CHECK: and32 w3, w2 ; CHECK: xor32 w3, -1 ; CHECK: stxw [r1 + 0], w3 @@ -137,7 +139,7 @@ entry: ; CHECK-LABEL: test_load_or_32 ; CHECK: ldxw w0, [r1 + 0] -; CHECK: mov32 w3, w0 +; CHECK: mov64 w3, w0 ; CHECK: or32 w3, w2 ; CHECK: stxw [r1 + 0], w3 define dso_local i32 @test_load_or_32(i32* nocapture %p, i32 %v) local_unnamed_addr { @@ -159,7 +161,7 @@ entry: ; CHECK-LABEL: test_load_xor_32 ; CHECK: ldxw w0, [r1 + 0] -; CHECK: mov32 w3, w0 +; CHECK: mov64 w3, w0 ; CHECK: xor32 w3, w2 ; CHECK: stxw [r1 + 0], w3 define dso_local i32 @test_load_xor_32(i32* nocapture %p, i32 %v) local_unnamed_addr { @@ -181,15 +183,11 @@ entry: ; CHECK-LABEL: test_min_32 ; CHECK: ldxw w0, [r1 + 0] -; CHECK: mov64 r4, r0 -; CHECK: lsh64 r4, 32 -; CHECK: arsh64 r4, 32 -; CHECK: mov32 r5, w2 -; CHECK: lsh64 r5, 32 -; CHECK: arsh64 r5, 32 -; CHECK: mov32 w3, w0 -; CHECK: jslt r4, r5, LBB16_2 -; CHECK: mov32 w3, w2 +; CHECK: mov32 r4, w2 +; CHECK: mov32 r5, w0 +; CHECK: mov64 w3, w0 +; CHECK: jsgt r4, r5, LBB16_2 +; CHECK: mov64 w3, w2 ; CHECK: stxw [r1 + 0], w3 define dso_local i32 @test_min_32(i32* nocapture %ptr, i32 %v) local_unnamed_addr #0 { entry: @@ -200,7 +198,7 @@ entry: ; CHECK-LABEL: test_min_64 ; CHECK: ldxdw r0, [r1 + 0] ; CHECK: mov64 r3, r0 -; CHECK: jslt r0, r2, +; CHECK: jsgt r2, r0, ; CHECK: mov64 r3, r2 ; CHECK: stxdw [r1 + 0], r3 define dso_local i64 @test_min_64(i64* nocapture %ptr, i64 %v) local_unnamed_addr #0 { @@ -211,15 +209,11 @@ entry: ; CHECK-LABEL: test_max_32 ; CHECK: ldxw w0, [r1 + 0] -; CHECK: mov64 r4, r0 -; CHECK: lsh64 r4, 32 -; CHECK: arsh64 r4, 32 +; CHECK: mov32 r4, w0 ; CHECK: mov32 r5, w2 -; CHECK: lsh64 r5, 32 -; CHECK: arsh64 r5, 32 -; CHECK: mov32 w3, w0 +; CHECK: mov64 w3, w0 ; CHECK: jsgt r4, r5, LBB18_2 -; CHECK: mov32 w3, w2 +; CHECK: mov64 w3, w2 ; CHECK: stxw [r1 + 0], w3 define dso_local i32 @test_max_32(i32* nocapture %ptr, i32 %v) local_unnamed_addr #0 { entry: @@ -241,10 +235,11 @@ entry: ; CHECK-LABEL: test_umin_32 ; CHECK: ldxw w0, [r1 + 0] -; CHECK: mov32 r4, w2 -; CHECK: mov32 w3, w0 -; CHECK: jlt r0, r4, -; CHECK: mov32 w3, w2 +; CHECK: mov64 r4, w2 +; CHECK: mov64 r5, w0 +; CHECK: mov64 w3, w0 +; CHECK: jgt r4, r5, +; CHECK: mov64 w3, w2 ; CHECK: stxw [r1 + 0], w3 define dso_local i32 @test_umin_32(i32* nocapture %ptr, i32 %v) local_unnamed_addr #0 { entry: @@ -255,7 +250,7 @@ entry: ; CHECK-LABEL: test_umin_64 ; CHECK: ldxdw r0, [r1 + 0] ; CHECK: mov64 r3, r0 -; CHECK: jlt r0, r2, +; CHECK: jgt r2, r0, ; CHECK: mov64 r3, r2 ; CHECK: stxdw [r1 + 0], r3 define dso_local i64 @test_umin_64(i64* nocapture %ptr, i64 %v) local_unnamed_addr #0 { @@ -266,10 +261,11 @@ entry: ; CHECK-LABEL: test_umax_32 ; CHECK: ldxw w0, [r1 + 0] -; CHECK: mov32 r4, w2 -; CHECK: mov32 w3, w0 -; CHECK: jgt r0, r4, -; CHECK: mov32 w3, w2 +; CHECK: mov64 r4, w0 +; CHECK: mov64 r5, w2 +; CHECK: mov64 w3, w0 +; CHECK: jgt r4, r5 +; CHECK: mov64 w3, w2 ; CHECK: stxw [r1 + 0], w3 define dso_local i32 @test_umax_32(i32* nocapture %ptr, i32 %v) local_unnamed_addr #0 { entry: @@ -305,8 +301,9 @@ entry: ; CHECK-LABEL: test_load_32 ; CHECK: ldxw w0, [r1 + 0] ; CHECK: mov32 w2, 0 -; CHECK: jeq r0, 0, LBB25_2 -; CHECK: mov32 w2, w0 +; CHECK: mov32 r3, w0 +; CHECK: jeq r3, 0, LBB25_2 +; CHECK: mov64 w2, w0 ; CHECK: LBB25_2: ; CHECK: stxw [r1 + 0], w2 define dso_local i32 @test_load_32(ptr nocapture %p) local_unnamed_addr { @@ -333,8 +330,9 @@ entry: ; CHECK-LABEL: test_weak_cas_32 ; CHECK: ldxw w4, [r1 + 0] -; CHECK: mov32 r2, w2 -; CHECK: jeq r4, r2, +; CHECK: mov64 r5, w4 +; CHECK: mov64 r2, w2 +; CHECK: jeq r5, r2, ; CHECK: stxw [r1 + 0], w3 define dso_local void @test_weak_cas_32(i32* nocapture %p, i32 %old, i32 %new) local_unnamed_addr { entry: diff --git a/llvm/test/CodeGen/SBF/br_cc_sext.ll b/llvm/test/CodeGen/SBF/br_cc_sext.ll new file mode 100644 index 00000000000000..bca0722fa01631 --- /dev/null +++ b/llvm/test/CodeGen/SBF/br_cc_sext.ll @@ -0,0 +1,129 @@ +; RUN: llc -march=sbf -mattr=+alu32,+explicit-sext -verify-machineinstrs < %s | FileCheck %s + +; ModuleID = 'test.c' +source_filename = "test.c" +target datalayout = "e-m:e-p:64:64-i64:64-n32:64-S128" +target triple = "sbf" + +; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +define dso_local noundef i32 @doThis(i32 noundef %a, i32 noundef %b) local_unnamed_addr #0 { +entry: + %rem = srem i32 %a, %b + ret i32 %rem +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +define dso_local i32 @test_one(i32 noundef %a, i32 noundef %b, ptr %c) local_unnamed_addr #0 { +entry: +; Sign extension before comparison with immediate value +; CHECK-LABEL: test_one +; CHECK: mov32 r1, w1 +; CHECK: jeq r1, -1, LBB1_2 + %ld = load i32, ptr %c, align 4 + %cmp = icmp ult i32 %ld, -1 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + %add = add nsw i32 %a, 9 + br label %if.end + +if.else: ; preds = %entry + %rem.i = srem i32 %b, %a + %sub = sub nsw i32 9, %rem.i + br label %if.end + +if.end: ; preds = %if.else, %if.then + %f.0 = phi i32 [ %add, %if.then ], [ %sub, %if.else ] + %add1 = add nsw i32 %f.0, 90 + ret i32 %add1 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +define dso_local i32 @test_two(i32 noundef %a, i32 noundef %b, ptr %c) local_unnamed_addr #0 { +entry: +; Sign extension before comparison with immediate value +; CHECK-LABEL: test_two +; CHECK: mov32 r1, w1 +; CHECK: jsgt r1, -2, LBB2_2 + %ld = load i32, ptr %c, align 4 + %cmp = icmp slt i32 %ld, -1 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + %add = add nsw i32 %a, 9 + br label %if.end + +if.else: ; preds = %entry + %rem.i = srem i32 %b, %a + %sub = sub nsw i32 9, %rem.i + br label %if.end + +if.end: ; preds = %if.else, %if.then + %f.0 = phi i32 [ %add, %if.then ], [ %sub, %if.else ] + %add1 = add nsw i32 %f.0, 90 + ret i32 %add1 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +define dso_local i32 @test_three(i32 noundef %a, i32 noundef %b, ptr %c) local_unnamed_addr #0 { +entry: +; Sign extension for signed comparison +; CHECK-LABEL: test_three +; CHECK: mov32 r1, w2 +; CHECK: ldxw w3, [r3 + 0] +; CHECK: mov32 r3, w3 +; CHECK: jsge r3, r1, LBB3_2 + %ld = load i32, ptr %c, align 4 + %cmp = icmp slt i32 %ld, %b + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + %add = add nsw i32 %a, 9 + br label %if.end + +if.else: ; preds = %entry + %rem.i = srem i32 %b, %a + %sub = sub nsw i32 9, %rem.i + br label %if.end + +if.end: ; preds = %if.else, %if.then + %f.0 = phi i32 [ %add, %if.then ], [ %sub, %if.else ] + %add1 = add nsw i32 %f.0, 90 + ret i32 %add1 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +define dso_local i32 @test_four(i32 noundef %a, i32 noundef %b, ptr %c) local_unnamed_addr #0 { +entry: +; Zero extension for unsigned comparison +; CHECK-LABEL: test_four +; CHECK: mov64 w0, w1 +; CHECK: ldxw w1, [r3 + 0] +; CHECK: jge r1, r2, LBB4_2 + %ld = load i32, ptr %c, align 4 + %cmp = icmp ult i32 %ld, %b + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + %add = add nsw i32 %a, 9 + br label %if.end + +if.else: ; preds = %entry + %rem.i = srem i32 %b, %a + %sub = sub nsw i32 9, %rem.i + br label %if.end + +if.end: ; preds = %if.else, %if.then + %f.0 = phi i32 [ %add, %if.then ], [ %sub, %if.else ] + %add1 = add nsw i32 %f.0, 90 + ret i32 %add1 +} + +attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+solana" } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"frame-pointer", i32 2} +!2 = !{!"clang version 18.1.7 (https://github.com/solana-labs/llvm-project.git 9fd466387b898c6e320f31dbb8b7766507d1e6ae)"} diff --git a/llvm/test/CodeGen/SBF/remove_truncate_7.ll b/llvm/test/CodeGen/SBF/remove_truncate_7.ll index a0df2f86d1f1e7..fbc89d8c1fe8fd 100644 --- a/llvm/test/CodeGen/SBF/remove_truncate_7.ll +++ b/llvm/test/CodeGen/SBF/remove_truncate_7.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=sbf -mattr=+alu32 -verify-machineinstrs | FileCheck %s +; RUN: llc < %s -march=sbf -mattr=+alu32,+explicit-sext -verify-machineinstrs | FileCheck %s ; ; Source: ; struct __sk_buff {