diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3801,9 +3801,17 @@ auto *FrozenMaybePoisonOperand = new FreezeInst( MaybePoisonOperand->get(), MaybePoisonOperand->get()->getName() + ".fr"); - + auto *IP = dyn_cast(MaybePoisonOperand->get()); replaceUse(*MaybePoisonOperand, FrozenMaybePoisonOperand); - FrozenMaybePoisonOperand->insertBefore(OrigOpInst); + if (IP) { + if (isa(IP)) + IP->getParent()->getInstList().insert( + IP->getParent()->getFirstInsertionPt(), FrozenMaybePoisonOperand); + else + FrozenMaybePoisonOperand->insertAfter(IP); + } else { + FrozenMaybePoisonOperand->insertBefore(OrigOpInst); + } return OrigOp; } diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll --- a/llvm/test/Transforms/InstCombine/freeze.ll +++ b/llvm/test/Transforms/InstCombine/freeze.ll @@ -594,5 +594,26 @@ ret void } - - +declare i1 @mock_use(i64, i64) +define i1 @propagate_freeze(i32 %0, i32 noundef %1) { +; CHECK-LABEL: @propagate_freeze( +; CHECK-NEXT: [[DOTFR:%.*]] = freeze i32 [[TMP0:%.*]] +; CHECK-NEXT: [[DR:%.*]] = lshr i32 [[DOTFR]], 2 +; CHECK-NEXT: [[IDX1:%.*]] = zext i32 [[DR]] to i64 +; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[DR]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], [[TMP1:%.*]] +; CHECK-NEXT: [[IDX2:%.*]] = zext i32 [[DR]] to i64 +; CHECK-NEXT: [[V:%.*]] = call i1 @mock_use(i64 [[IDX1]], i64 [[IDX2]]) +; CHECK-NEXT: [[RET:%.*]] = and i1 [[V]], [[CMP]] +; CHECK-NEXT: ret i1 [[RET]] +; + %dr = lshr i32 %0, 2 + %idx1 = zext i32 %dr to i64 + %add = add i32 %dr, 1 + %cmp = icmp slt i32 %add, %1 + %cmp.fr = freeze i1 %cmp + %idx2 = zext i32 %dr to i64 + %v = call i1 @mock_use(i64 %idx1, i64 %idx2) + %ret = and i1 %v, %cmp.fr + ret i1 %ret +}