From: Roman Lebedev Date: Tue, 2 Jul 2019 12:54:48 +0000 (+0000) Subject: [InstCombine] Shift amount reassociation: fixup constantexpr handling (PR42484) X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3c7482c607180cb689ff2fda2cd79decf59b41d8;p=llvm [InstCombine] Shift amount reassociation: fixup constantexpr handling (PR42484) I was actually wondering if there was some nicer way than m_Value()+cast, but apparently what i was really "subconsciously" thinking about was correctness issue. hasNoUnsignedWrap()/hasNoUnsignedWrap() exist for Instruction, not for BinaryOperator, so let's just use m_Instruction(), thus both avoiding a cast, and a crash. Fixes https://bugs.llvm.org/show_bug.cgi?id=42484, https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15587 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364915 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineShifts.cpp b/lib/Transforms/InstCombine/InstCombineShifts.cpp index 1558795b530..0bbecde2184 100644 --- a/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -29,12 +29,12 @@ static Instruction * reassociateShiftAmtsOfTwoSameDirectionShifts(BinaryOperator *Sh0, const SimplifyQuery &SQ) { // Look for: (x shiftopcode ShAmt0) shiftopcode ShAmt1 - Value *X, *ShAmt1, *Sh1Value, *ShAmt0; + Value *X, *ShAmt1, *ShAmt0; + Instruction *Sh1; if (!match(Sh0, m_Shift(m_CombineAnd(m_Shift(m_Value(X), m_Value(ShAmt1)), - m_Value(Sh1Value)), + m_Instruction(Sh1)), m_Value(ShAmt0)))) return nullptr; - auto *Sh1 = cast(Sh1Value); // The shift opcodes must be identical. Instruction::BinaryOps ShiftOpcode = Sh0->getOpcode(); diff --git a/test/Transforms/InstCombine/shift-amount-reassociation.ll b/test/Transforms/InstCombine/shift-amount-reassociation.ll index f7cd0791482..e124a035861 100644 --- a/test/Transforms/InstCombine/shift-amount-reassociation.ll +++ b/test/Transforms/InstCombine/shift-amount-reassociation.ll @@ -154,6 +154,21 @@ define i32 @t11_shl_nsw_flag_preservation(i32 %x, i32 %y) { ret i32 %t3 } +; Reduced from https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15587 +@X = external global i32 +define i64 @constantexpr() { +; CHECK-LABEL: @constantexpr( +; CHECK-NEXT: ret i64 0 +; + %A = alloca i64 + %L = load i64, i64* %A + %V = add i64 ptrtoint (i32* @X to i64), 0 + %B2 = shl i64 %V, 0 + %B4 = ashr i64 %B2, %L + %B = and i64 undef, %B4 + ret i64 %B +} + ; No one-use tests since we will only produce a single instruction here. ; Negative tests