https://llvm.org/bugs/show_bug.cgi?id=28441
Bug ID: 28441 Summary: common predicate value is not hoisted Product: libraries Version: trunk Hardware: PC OS: All Status: NEW Severity: normal Priority: P Component: Transformation Utilities Assignee: unassignedb...@nondot.org Reporter: spatel+l...@rotateright.com CC: llvm-bugs@lists.llvm.org Classification: Unclassified extern void bar(int); void f(int x, int y) { if (x && y == 1) bar(8000); if (x && y == 2) bar(9000); } ICC checks 'x' first and effectively turns this code into: void g(int x, int y) { if (x) { if (y == 1) bar(8000); if (y == 2) bar(9000); } } LLVM does not, and the code size penalty is substantial (not sure if perf is better, but seems like it shouldn't be worse): $ clang ifand.c -O1 -fomit-frame-pointer -c $ otool -tv ifand.o _f: 0000000000000000 pushq %rbp 0000000000000001 pushq %rbx 0000000000000002 pushq %rax 0000000000000003 movl %esi, %ebx 0000000000000005 movl %edi, %ebp 0000000000000007 testl %ebp, %ebp 0000000000000009 je 0x1a 000000000000000b cmpl $0x1, %ebx 000000000000000e jne 0x1a 0000000000000010 movl $0x1f40, %edi ## imm = 0x1F40 0000000000000015 callq 0x1a 000000000000001a testl %ebp, %ebp 000000000000001c je 0x33 000000000000001e cmpl $0x2, %ebx 0000000000000021 jne 0x33 0000000000000023 movl $0x2328, %edi ## imm = 0x2328 0000000000000028 addq $0x8, %rsp 000000000000002c popq %rbx 000000000000002d popq %rbp 000000000000002e jmp 0x33 0000000000000033 addq $0x8, %rsp 0000000000000037 popq %rbx 0000000000000038 popq %rbp 0000000000000039 retq 000000000000003a nopw (%rax,%rax) _g: 0000000000000040 testl %edi, %edi 0000000000000042 je 0x58 0000000000000044 cmpl $0x2, %esi 0000000000000047 je 0x59 0000000000000049 cmpl $0x1, %esi 000000000000004c jne 0x58 000000000000004e movl $0x1f40, %edi ## imm = 0x1F40 0000000000000053 jmp 0x58 0000000000000058 retq 0000000000000059 movl $0x2328, %edi ## imm = 0x2328 000000000000005e jmp 0x63 Even if there's disagreement on which form is better, I think the IR should be canonicalized to one or the other, allowing the backend to optimize whichever way it wants to: $ ./clang ifand.c -O1 -fomit-frame-pointer -S -o - -emit-llvm ; ModuleID = 'ifand.c' source_filename = "ifand.c" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.11.0" ; Function Attrs: nounwind ssp uwtable define void @f(i32 %x, i32 %y) local_unnamed_addr #0 { entry: %tobool = icmp ne i32 %x, 0 %cmp = icmp eq i32 %y, 1 %or.cond = and i1 %tobool, %cmp br i1 %or.cond, label %if.then, label %if.end if.then: ; preds = %entry tail call void @bar(i32 8000) #2 br label %if.end if.end: ; preds = %if.then, %entry %cmp3 = icmp eq i32 %y, 2 %or.cond6 = and i1 %tobool, %cmp3 br i1 %or.cond6, label %if.then4, label %if.end5 if.then4: ; preds = %if.end tail call void @bar(i32 9000) #2 br label %if.end5 if.end5: ; preds = %if.then4, %if.end ret void } declare void @bar(i32) local_unnamed_addr #1 ; Function Attrs: nounwind ssp uwtable define void @g(i32 %x, i32 %y) local_unnamed_addr #0 { entry: %tobool = icmp eq i32 %x, 0 br i1 %tobool, label %if.end5, label %if.then if.then: ; preds = %entry switch i32 %y, label %if.end5 [ i32 1, label %if.then1 i32 2, label %if.then3 ] if.then1: ; preds = %if.then tail call void @bar(i32 8000) #2 br label %if.end5 if.then3: ; preds = %if.then tail call void @bar(i32 9000) #2 br label %if.end5 if.end5: ; preds = %if.then1, %if.then, %entry, %if.then3 ret void } -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs