diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -918,19 +918,15 @@ SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1)) return I; } else { // fshl is a rotate - // Avoid converting rotate into funnel shift. - // Only simplify if one operand is constant. - KnownBits LHSKnown = computeKnownBits(I->getOperand(0), Depth + 1, I); - if (DemandedMaskLHS.isSubsetOf(LHSKnown.Zero | LHSKnown.One)) { + // Avoid converting rotate into funnel shift. + // Only simplify if one operand is constant. + LHSKnown = computeKnownBits(I->getOperand(0), Depth + 1, I); + if (DemandedMaskLHS.isSubsetOf(LHSKnown.Zero | LHSKnown.One)) replaceOperand(*I, 0, Constant::getIntegerValue(VTy, LHSKnown.One)); - return I; - } - KnownBits RHSKnown = computeKnownBits(I->getOperand(1), Depth + 1, I); - if (DemandedMaskRHS.isSubsetOf(RHSKnown.Zero | RHSKnown.One)) { + RHSKnown = computeKnownBits(I->getOperand(1), Depth + 1, I); + if (DemandedMaskRHS.isSubsetOf(RHSKnown.Zero | RHSKnown.One)) replaceOperand(*I, 1, Constant::getIntegerValue(VTy, RHSKnown.One)); - return I; - } } Known.Zero = LHSKnown.Zero.shl(ShiftAmt) | diff --git a/llvm/test/Transforms/InstCombine/2023-07-13-arm-infiniteloop.ll b/llvm/test/Transforms/InstCombine/2023-07-13-arm-infiniteloop.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/2023-07-13-arm-infiniteloop.ll @@ -0,0 +1,68 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 +; RUN: opt -S -passes=instcombine < %s | FileCheck %s +target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "armv4t-unknown-linux-gnueabi" + +define i32 @__fswab64(i64 %val, i32 %conv) { +; CHECK-LABEL: define i32 @__fswab64 +; CHECK-SAME: (i64 [[VAL:%.*]], i32 [[CONV:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[VAL]], 32 +; CHECK-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP0]] to i32 +; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.is.constant.i32(i32 [[CONV1]]) +; CHECK-NEXT: br i1 [[TMP1]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, ptr null, align 2147483648 +; CHECK-NEXT: br label [[IF_END:%.*]] +; CHECK: if.else: +; CHECK-NEXT: [[OR:%.*]] = call i32 @llvm.fshl.i32(i32 [[CONV1]], i32 [[CONV]], i32 16) +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[T_0:%.*]] = phi i32 [ [[OR]], [[IF_ELSE]] ], [ [[TMP2]], [[IF_THEN]] ] +; CHECK-NEXT: [[SHR2:%.*]] = lshr i32 [[T_0]], 1 +; CHECK-NEXT: ret i32 [[SHR2]] +; +entry: + %0 = lshr i64 %val, 32 + %conv1 = trunc i64 %0 to i32 + %1 = call i1 @llvm.is.constant.i32(i32 %conv1) + br i1 %1, label %if.else, label %if.then + +if.then: ; preds = %entry + %2 = load volatile i32, ptr null, align 2147483648 + br label %if.end + +if.else: ; preds = %entry + %or = call i32 @llvm.fshl.i32(i32 %conv1, i32 %conv, i32 16) + br label %if.end + +if.end: ; preds = %if.else, %if.then + %t.0 = phi i32 [ %or, %if.else ], [ %2, %if.then ] + %shr2 = lshr i32 %t.0, 1 + ret i32 %shr2 +} + +; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) +declare i1 @llvm.is.constant.i32(i32) #0 + +define void @bpf_prog_calc_tag(ptr %bpf_prog_calc_tag___trans_tmp_3, i32 %0) { +; CHECK-LABEL: define void @bpf_prog_calc_tag +; CHECK-SAME: (ptr [[BPF_PROG_CALC_TAG___TRANS_TMP_3:%.*]], i32 [[TMP0:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64 +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @__fswab64(i64 [[CONV]], i32 0) +; CHECK-NEXT: store i32 [[CALL1]], ptr [[BPF_PROG_CALC_TAG___TRANS_TMP_3]], align 4 +; CHECK-NEXT: ret void +; +entry: + %conv = zext i32 %0 to i64 + %call1 = call i32 @__fswab64(i64 %conv, i32 0) + store i32 %call1, ptr %bpf_prog_calc_tag___trans_tmp_3, align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare i32 @llvm.fshl.i32(i32, i32, i32) #1 + +attributes #0 = { convergent nocallback nofree nosync nounwind willreturn memory(none) } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }