I have ran across a case where the function isIdenticalTo is return true for instructions that are not equivalent. The instructions in question are load/store instructions, and is causing a problem with MachineBranchFolding. The problem is this, I have two branches of a switch statement that are identical, except for the size of the store. Here is some cut-down LLVM-IR to showcase the issue:
switch.case: ; preds = %if.end
%tmp53 = extractelement <4 x i32> %format, i32 1 ; [#uses=1]
switch i32 %tmp53, label %if.then [
i32 1, label %switch.case55
i32 2, label %switch.case61
]
switch.case55: ; preds = %switch.case
%arrayidx = getelementptr i8 addrspace(1)* %conv3, i32 %tmp22 ; <i8 addrspace(1)*> [#uses=1]
%tmp59 = extractelement <4 x i32> %9, i32 0 ; [#uses=1]
%conv60 = trunc i32 %tmp59 to i8 ; [#uses=1]
store i8 %conv60, i8 addrspace(1)* %arrayidx
ret void
switch.case61: ; preds = %switch.case
%arrayidx64 = getelementptr i16 addrspace(1)* %conv, i32 %tmp22 ; <i16 addrspace(1)*> [#uses=1]
%tmp66 = extractelement <4 x i32> %9, i32 0 ; [#uses=1]
%conv67 = trunc i32 %tmp66 to i16 ; [#uses=1]
store i16 %conv67, i16 addrspace(1)* %arrayidx64
ret void
Notice how except for the sizes of the pointer, the sequence is the same. This translates into the following for my backend at the MI level.
BB#9: derived from LLVM BB %switch.case55
Live Ins: %R258 %R260 %R259
Predecessors according to CFG: BB#8
%R257 = CUSTOM_ADD_i32 %R260, %R258
%R258 = VEXTRACT_v4i32 %R259, 1
GLOBALTRUNCSTORE_i32 %R258, %R257, 8; mem:ST1[%arrayidx]
RETURN
BB#10: derived from LLVM BB %switch.case61
Live Ins: %R258 %R260 %R259
Predecessors according to CFG: BB#7
%R257 = LOADCONST_i32 1
%R257 = SHL_i32 %R258, %R257
%R257 = CUSTOM_ADD_i32 %R260, %R257
%R258 = VEXTRACT_v4i32 %R259, 1
GLOBALTRUNCSTORE_i32 %R258, %R257, 8; mem:ST2[%arrayidx64]
RETURN
Notice how except for the memory operand size on the truncating store, the last three instructions in BB#7 is the same as BB#8.
Now looking at isIdenticalTo, I don’t see any checks on the memory size. Since I don’t encode this information in the instruction, because it is encoded in the memory object, two different instructions can be considered identical for different memory sizes. I believe this is incorrect.
Here is my proposed patch for the issue:
Index: MachineInstr.cpp
MI_isIdenticalTo.patch (1.22 KB)