diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index abcde1ded6b2ce..c57a111a5e2041 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -539,12 +539,16 @@ static Value *threadBinOpOverPHI(Instruction::BinaryOps Opcode, Value *LHS, // Evaluate the BinOp on the incoming phi values. Value *CommonValue = nullptr; - for (Value *Incoming : PI->incoming_values()) { + for (Use &Incoming : PI->incoming_values()) { // If the incoming value is the phi node itself, it can safely be skipped. if (Incoming == PI) continue; - Value *V = PI == LHS ? simplifyBinOp(Opcode, Incoming, RHS, Q, MaxRecurse) - : simplifyBinOp(Opcode, LHS, Incoming, Q, MaxRecurse); + Instruction *InTI = PI->getIncomingBlock(Incoming)->getTerminator(); + Value *V = PI == LHS + ? simplifyBinOp(Opcode, Incoming, RHS, + Q.getWithInstruction(InTI), MaxRecurse) + : simplifyBinOp(Opcode, LHS, Incoming, + Q.getWithInstruction(InTI), MaxRecurse); // If the operation failed to simplify, or simplified to a different value // to previously, then give up. if (!V || (CommonValue && V != CommonValue)) diff --git a/llvm/test/Transforms/InstSimplify/phi.ll b/llvm/test/Transforms/InstSimplify/phi.ll index 14f17674bc5249..c97326ea05137e 100644 --- a/llvm/test/Transforms/InstSimplify/phi.ll +++ b/llvm/test/Transforms/InstSimplify/phi.ll @@ -153,7 +153,8 @@ EXIT: ret i8 %r } -; FIXME: This is a miscompile. +; Should not fold srem to -1 due to incorrect context instruction when +; threading over phi. define i32 @pr61312() { ; CHECK-LABEL: @pr61312( ; CHECK-NEXT: entry: @@ -166,7 +167,8 @@ define i32 @pr61312() { ; CHECK-NEXT: [[DEC]] = add nsw i32 [[A_0]], -1 ; CHECK-NEXT: br label [[FOR_COND]] ; CHECK: for.end: -; CHECK-NEXT: ret i32 -1 +; CHECK-NEXT: [[REM:%.*]] = srem i32 -1, [[A_0]] +; CHECK-NEXT: ret i32 [[REM]] ; entry: br label %for.cond