When optimizing x-(-A) to x+A, the current logic of preserving nsw/nuw has a hole. For example, the current logic transforms "x -nsw (0-A)" to "x +nsw A". However, when x = a = INT_MIN = -2^31, "x -nsw (0 - A)" is defined but "x +nsw A" returns a poison value. The following test case exposes the bug. define i32 @test37(i32 %A, i32 %x) { %B = sub i32 0, %A %C = sub nsw i32 %x, %B ret i32 %C ; CHECK-LABEL: @test37( ; CHECK: %C = add i32 %x, %A ; CHECK: ret i32 %C } To fix this issue, we need to consider the nsw/nuw of both minuses in x-(-A). If both of them are marked nsw/nuw, we can preserve the nsw/nuw in the result x+A.
Fixed with r214384 and r214385.