diff --git a/lib/Transforms/InstCombine/InstCombineNegator.cpp b/lib/Transforms/InstCombine/InstCombineNegator.cpp index 9033f389cd6..bfecfe98a59 100644 --- a/lib/Transforms/InstCombine/InstCombineNegator.cpp +++ b/lib/Transforms/InstCombine/InstCombineNegator.cpp @@ -244,6 +244,13 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) { } switch (I->getOpcode()) { + case Instruction::Freeze: { + // `freeze` is negatible if its operand is negatible. + Value *NegOp = negate(I->getOperand(0), Depth + 1); + if (!NegOp) // Early return. + return nullptr; + return Builder.CreateFreeze(NegOp, I->getName() + ".neg"); + } case Instruction::PHI: { // `phi` is negatible if all the incoming values are negatible. auto *PHI = cast(I); diff --git a/test/Transforms/InstCombine/sub-of-negatible.ll b/test/Transforms/InstCombine/sub-of-negatible.ll index 01889eaf564..0755ebfff16 100644 --- a/test/Transforms/InstCombine/sub-of-negatible.ll +++ b/test/Transforms/InstCombine/sub-of-negatible.ll @@ -1214,9 +1214,9 @@ define i8 @dont_negate_ordinary_select(i8 %x, i8 %y, i8 %z, i1 %c) { ; Freeze is transparent as far as negation is concerned define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) { ; CHECK-LABEL: @negate_freeze( -; CHECK-NEXT: [[T0:%.*]] = sub i4 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[T1:%.*]] = freeze i4 [[T0]] -; CHECK-NEXT: [[T2:%.*]] = sub i4 [[Z:%.*]], [[T1]] +; CHECK-NEXT: [[T0_NEG:%.*]] = sub i4 [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[T1_NEG:%.*]] = freeze i4 [[T0_NEG]] +; CHECK-NEXT: [[T2:%.*]] = add i4 [[T1_NEG]], [[Z:%.*]] ; CHECK-NEXT: ret i4 [[T2]] ; %t0 = sub i4 %x, %y