On the ppc64le platform, I found that if ir has the following form,
define i64 @addze1(i64 %x, i64 %z) local_unnamed_addr #0 { entry: %cmp = icmp ne i64 %z, CONSTANT (-32767 <= CONSTANT <= 32768) %conv1 = zext i1 %cmp to i64 %add = add nsw i64 %conv1, %x ret i64 %add }
we can optimize it to the form below.
when C == 0 --> addze X, (addic Z, -1)) / add X, (zext(setne Z, C))-- \ when -32768 <= -C <= 32767 && C != 0 --> addze X, (addic (addi Z, -C), -1)
Besides , if ir has the following form,
define i64 @addze2(i64 %x, i64 %z) local_unnamed_addr #0 { entry: %cmp = icmp eq i64 %z, CONSTANT (-32767 <= CONSTANT <= 32768) %conv1 = zext i1 %cmp to i64 %add = add nsw i64 %conv1, %x ret i64 %add }
we can optimize it to the form below.
when C == 0 --> addze X, (subfic Z, 0) / add X, (zext(setne Z, C))-- \ when -32768 <= -C <= 32767 && C != 0 --> addze X, (subfic (addi Z, -C), 0)
I think it might be clearer if you show that it is only the carry from the addic that is being used in the addze (since addze only takes one explicit operand). Perhaps something like:
addze X, (addic Z, -1).1 or addze X, (addic Z, -1).carry