Another use said there is not a well known use, but I think that OP_IFDUP is super nifty. Adding my response (years later) to share the knowledge in case someone else comes across this post.
Consider the following script:
OP_DUP
OP_0
<2>
OP_WITHIN
OP_VERIFY
OP_IFDUP
OP_NOTIF
... sub program 0
OP_0
OP_ENDIF
OP_1SUB
OP_IFDUP
OP_NOTIF
... sub program 1
OP_0
OP_ENDIF
OP_1SUB
OP_IFDUP
OP_NOTIF
... sub program 2
OP_ENDIF
OP_1
This program emulates a switch!
switch(x) {
case 0:
// program 0
case 1:
// program 1
case 2:
// program 2
default:
assert(0);
}
But is also slightly more powerful because the last OP_0 per branch can specify if any future branches should also execute (can be used for fall-through behavior, if there is a logical clause common to a group!).
Compare to the more "straightforward" solutions using OP_IF and OP_EQUAL, there's a few more opcodes per branch, and more overall when n = 3. Further the need to push the number on the stack in the code can contribute more bytes for even bigger switches.
OP_DUP
<0>
OP_EQUAL
OP_IF
OP_DROP
... sub program 0
OP_0
OP_ENDIF
OP_DUP
<1>
OP_EQUAL
OP_IF
OP_DROP
... sub program 1
OP_0
OP_ENDIF
OP_DUP
<2>
OP_EQUAL
OP_IF
OP_DROP
... sub program 2
OP_ENDIF
OP_1